This guide demonstrates how to integrate Auth0 with any new or existing Python API built with Flask.If you haven’t created an API in your Auth0 dashboard yet, you can use the interactive selector to create a new Auth0 API or select an existing API that represents the project you want to integrate with.Alternatively, you can read our getting started guide that helps you set up your first API through the Auth0 dashboard.Every API in Auth0 is configured using an API Identifier that your application code will use as the Audience to validate the Access Token.
New to Auth0? Learn how Auth0 works and read about implementing API authentication and authorization using the OAuth 2.0 framework.
Permissions let you define how resources can be accessed on behalf of the user with a given access token. For example, you might choose to grant read access to the messages resource if users have the manager access level, and a write access to that resource if they have the administrator access level.You can define allowed permissions in the Permissions view of the Auth0 Dashboard’s APIs section.
This example uses the read:messages scope.
Add the following dependencies to your requirements.txt:
# /requirements.txt
flask

Authlib
We’re going to use a library called Authlib to create a ResourceProtector, which is a type of Flask decorator that protects our resources (API routes) with a given validator.The validator will validate the Access Token that we pass to the resource by checking that it has a valid signature and claims.We can use AuthLib’s JWTBearerTokenValidator validator with a few tweaks to make sure it conforms to our requirements on validating Access Tokens.To create our Auth0JWTBearerTokenValidator we need to pass it our domain and audience (API Identifier). It will then get the public key required to verify the token’s signature and pass it to the JWTBearerTokenValidator class.We’ll then override the class’s claims_options to make sure the token’s expiry, audience and issue claims are validated according to our requirements.Next we’ll create a Flask application with 3 API routes:
  • /api/publicA public endpoint that requires no authentication.
  • /api/privateA private endpoint that requires a valid Access Token JWT.
  • /api/private-scopedA private endpoint that requires a valid Access Token JWT that contains the given scope.
The protected routes will have a require_auth decorator which is a ResourceProtector that uses the Auth0JWTBearerTokenValidator we created earlier.To create the Auth0JWTBearerTokenValidator we’ll pass it our tenant’s domain and the API Identifier of the API we created earlier.The require_auth decorator on the private_scoped route accepts an additional argument "read:messages", which checks the Access Token for the Permission (Scope) we created earlier.

Make a Call to Your API

To make calls to your API, you need an Access Token. You can get an Access Token for testing purposes from the Test view in your API settings.Provide the Access Token as an Authorization header in your requests.
Tab panes
curl --request get \
--url 'http:///{yourDomain}/api_path' \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN_HERE'
var
client
=
new
RestClient
(
"http:///{yourDomain}/api_path"
)
;
var
request
=
new
RestRequest
(
Method
.
GET
)
;
request
.
AddHeader
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
;
IRestResponse
response
=
client
.
Execute
(
request
)
;
package
main
import
(
"fmt"
"net/http"
"io/ioutil"
)
func
main
(
)
{
url
:=
"http:///{yourDomain}/api_path"
req
,
_
:=
http
.
NewRequest
(
"get"
,
url
,
nil
)
req
.
Header
.
Add
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
res
,
_
:=
http
.
DefaultClient
.
Do
(
req
)
defer
res
.
Body
.
Close
(
)
body
,
_
:=
ioutil
.
ReadAll
(
res
.
Body
)
fmt
.
Println
(
res
)
fmt
.
Println
(
string
(
body
)
)
}
HttpResponse
<
String
>
response
=
Unirest
.
get
(
"http:///{yourDomain}/api_path"
)
.
header
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
.
asString
(
)
;
var
axios
=
require
(
"axios"
)
.
default
;
var
options
=
{
method
:
'get'
,
url
:
'http:///{yourDomain}/api_path'
,
headers
:
{
authorization
:
'Bearer YOUR_ACCESS_TOKEN_HERE'
}
}
;
axios
.
request
(
options
)
.
then
(
function
(
response
)
{
console
.
log
(
response
.
data
)
;
}
)
.
catch
(
function
(
error
)
{
console
.
error
(
error
)
;
}
)
;
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN_HERE" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http:///{yourDomain}/api_path"]
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy

                                               timeoutInterval:10.0];

[request setHTTPMethod:@"get"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {

                                                NSLog(@&quot;%@&quot;, error);

                                            } else {

                                                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;

                                                NSLog(@&quot;%@&quot;, httpResponse);

                                            }

                                        }];

[dataTask resume];
$curl
=
curl_init
(
)
;
curl_setopt_array
(
$curl
,
[
CURLOPT_URL
=>
"http:///{yourDomain}/api_path"
,
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_ENCODING
=>
""
,
CURLOPT_MAXREDIRS
=>
10
,
CURLOPT_TIMEOUT
=>
30
,
CURLOPT_HTTP_VERSION
=>
CURL_HTTP_VERSION_1_1
,
CURLOPT_CUSTOMREQUEST
=>
"get"
,
CURLOPT_HTTPHEADER
=>
[
&
quot
;
authorization
:
Bearer
YOUR_ACCESS_TOKEN_HERE
&
quot
;
]
,
]
)
;
$response
=
curl_exec
(
$curl
)
;
$err
=
curl_error
(
$curl
)
;
curl_close
(
$curl
)
;
if
(
$err
)
{
echo
"cURL Error #:"
.
$err
;
}
else
{
echo
$response
;
}
import
http
.
client
conn
=
http
.
client
.
HTTPConnection
(
""
)
headers
=
{
'authorization'
:
"Bearer YOUR_ACCESS_TOKEN_HERE"
}
conn
.
request
(
"get"
,
"/{yourDomain}/api_path"
,
headers
=
headers
)
res
=
conn
.
getresponse
(
)
data
=
res
.
read
(
)
print
(
data
.
decode
(
"utf-8"
)
)
require
'uri'
require
'net/http'
url
=
URI
(
"http:///{yourDomain}/api_path"
)
http
=
Net
::
HTTP
.
new
(
url
.
host
,
url
.
port
)
request
=
Net
::
HTTP
::
Get
.
new
(
url
)
request
[
"authorization"
]
=
'Bearer YOUR_ACCESS_TOKEN_HERE'
response
=
http
.
request
(
request
)
puts response
.
read_body
import
Foundation
let
headers
=
[
"authorization"
:
"Bearer YOUR_ACCESS_TOKEN_HERE"
]
let
request
=
NSMutableURLRequest
(
url
:
NSURL
(
string
:
"http:///{yourDomain}/api_path"
)
!
as
URL
,
cachePolicy
:
.
useProtocolCachePolicy
,
timeoutInterval
:
10.0
)
request
.
httpMethod
=
"get"
request
.
allHTTPHeaderFields
=
headers
let
session
=
URLSession
.
shared
let
dataTask
=
session
.
dataTask
(
with
:
request
as
URLRequest
,
completionHandler
:
{
(
data
,
response
,
error
)
->
Void
in
if
(
error
!=
nil
)
{
print
(
error
)
}
else
{
let
httpResponse
=
response
as
?
HTTPURLResponse
print
(
httpResponse
)
}
}
)
dataTask
.
resume
(
)
Excellent work! If you made it this far, you should now have login, logout, and user profile information running in your application.This concludes our quickstart tutorial, but there is so much more to explore. To learn more about what you can do with Auth0, check out:
  • Auth0 Dashboard - Learn how to configure and manage your Auth0 tenant and applications
  • auth0-python SDK - Explore the SDK used in this tutorial more fully
  • Auth0 Marketplace - Discover integrations you can enable to extend Auth0’s functionality
Did it work?Any suggestion or typo?
1

Define permissions

Permissions let you define how resources can be accessed on behalf of the user with a given access token. For example, you might choose to grant read access to the messages resource if users have the manager access level, and a write access to that resource if they have the administrator access level.You can define allowed permissions in the Permissions view of the Auth0 Dashboard’s APIs section.
This example uses the read:messages scope.
2

Install dependencies

Add the following dependencies to your requirements.txt:
# /requirements.txt
flask

Authlib
3

Create the JWT validator

We’re going to use a library called Authlib to create a ResourceProtector, which is a type of Flask decorator that protects our resources (API routes) with a given validator.The validator will validate the Access Token that we pass to the resource by checking that it has a valid signature and claims.We can use AuthLib’s JWTBearerTokenValidator validator with a few tweaks to make sure it conforms to our requirements on validating Access Tokens.To create our Auth0JWTBearerTokenValidator we need to pass it our domain and audience (API Identifier). It will then get the public key required to verify the token’s signature and pass it to the JWTBearerTokenValidator class.We’ll then override the class’s claims_options to make sure the token’s expiry, audience and issue claims are validated according to our requirements.
4

Create a Flask application

Next we’ll create a Flask application with 3 API routes:
  • /api/publicA public endpoint that requires no authentication.
  • /api/privateA private endpoint that requires a valid Access Token JWT.
  • /api/private-scopedA private endpoint that requires a valid Access Token JWT that contains the given scope.
The protected routes will have a require_auth decorator which is a ResourceProtector that uses the Auth0JWTBearerTokenValidator we created earlier.To create the Auth0JWTBearerTokenValidator we’ll pass it our tenant’s domain and the API Identifier of the API we created earlier.The require_auth decorator on the private_scoped route accepts an additional argument "read:messages", which checks the Access Token for the Permission (Scope) we created earlier.

Make a Call to Your API

To make calls to your API, you need an Access Token. You can get an Access Token for testing purposes from the Test view in your API settings.Provide the Access Token as an Authorization header in your requests.
Tab panes
curl --request get \
--url 'http:///{yourDomain}/api_path' \
--header 'authorization: Bearer YOUR_ACCESS_TOKEN_HERE'
var
client
=
new
RestClient
(
"http:///{yourDomain}/api_path"
)
;
var
request
=
new
RestRequest
(
Method
.
GET
)
;
request
.
AddHeader
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
;
IRestResponse
response
=
client
.
Execute
(
request
)
;
package
main
import
(
"fmt"
"net/http"
"io/ioutil"
)
func
main
(
)
{
url
:=
"http:///{yourDomain}/api_path"
req
,
_
:=
http
.
NewRequest
(
"get"
,
url
,
nil
)
req
.
Header
.
Add
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
res
,
_
:=
http
.
DefaultClient
.
Do
(
req
)
defer
res
.
Body
.
Close
(
)
body
,
_
:=
ioutil
.
ReadAll
(
res
.
Body
)
fmt
.
Println
(
res
)
fmt
.
Println
(
string
(
body
)
)
}
HttpResponse
<
String
>
response
=
Unirest
.
get
(
"http:///{yourDomain}/api_path"
)
.
header
(
"authorization"
,
"Bearer YOUR_ACCESS_TOKEN_HERE"
)
.
asString
(
)
;
var
axios
=
require
(
"axios"
)
.
default
;
var
options
=
{
method
:
'get'
,
url
:
'http:///{yourDomain}/api_path'
,
headers
:
{
authorization
:
'Bearer YOUR_ACCESS_TOKEN_HERE'
}
}
;
axios
.
request
(
options
)
.
then
(
function
(
response
)
{
console
.
log
(
response
.
data
)
;
}
)
.
catch
(
function
(
error
)
{
console
.
error
(
error
)
;
}
)
;
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"authorization": @"Bearer YOUR_ACCESS_TOKEN_HERE" };
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http:///{yourDomain}/api_path"]
                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy

                                               timeoutInterval:10.0];

[request setHTTPMethod:@"get"];
[request setAllHTTPHeaderFields:headers];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
                                        completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

                                            if (error) {

                                                NSLog(@&quot;%@&quot;, error);

                                            } else {

                                                NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;

                                                NSLog(@&quot;%@&quot;, httpResponse);

                                            }

                                        }];

[dataTask resume];
$curl
=
curl_init
(
)
;
curl_setopt_array
(
$curl
,
[
CURLOPT_URL
=>
"http:///{yourDomain}/api_path"
,
CURLOPT_RETURNTRANSFER
=>
true
,
CURLOPT_ENCODING
=>
""
,
CURLOPT_MAXREDIRS
=>
10
,
CURLOPT_TIMEOUT
=>
30
,
CURLOPT_HTTP_VERSION
=>
CURL_HTTP_VERSION_1_1
,
CURLOPT_CUSTOMREQUEST
=>
"get"
,
CURLOPT_HTTPHEADER
=>
[
&
quot
;
authorization
:
Bearer
YOUR_ACCESS_TOKEN_HERE
&
quot
;
]
,
]
)
;
$response
=
curl_exec
(
$curl
)
;
$err
=
curl_error
(
$curl
)
;
curl_close
(
$curl
)
;
if
(
$err
)
{
echo
"cURL Error #:"
.
$err
;
}
else
{
echo
$response
;
}
import
http
.
client
conn
=
http
.
client
.
HTTPConnection
(
""
)
headers
=
{
'authorization'
:
"Bearer YOUR_ACCESS_TOKEN_HERE"
}
conn
.
request
(
"get"
,
"/{yourDomain}/api_path"
,
headers
=
headers
)
res
=
conn
.
getresponse
(
)
data
=
res
.
read
(
)
print
(
data
.
decode
(
"utf-8"
)
)
require
'uri'
require
'net/http'
url
=
URI
(
"http:///{yourDomain}/api_path"
)
http
=
Net
::
HTTP
.
new
(
url
.
host
,
url
.
port
)
request
=
Net
::
HTTP
::
Get
.
new
(
url
)
request
[
"authorization"
]
=
'Bearer YOUR_ACCESS_TOKEN_HERE'
response
=
http
.
request
(
request
)
puts response
.
read_body
import
Foundation
let
headers
=
[
"authorization"
:
"Bearer YOUR_ACCESS_TOKEN_HERE"
]
let
request
=
NSMutableURLRequest
(
url
:
NSURL
(
string
:
"http:///{yourDomain}/api_path"
)
!
as
URL
,
cachePolicy
:
.
useProtocolCachePolicy
,
timeoutInterval
:
10.0
)
request
.
httpMethod
=
"get"
request
.
allHTTPHeaderFields
=
headers
let
session
=
URLSession
.
shared
let
dataTask
=
session
.
dataTask
(
with
:
request
as
URLRequest
,
completionHandler
:
{
(
data
,
response
,
error
)
->
Void
in
if
(
error
!=
nil
)
{
print
(
error
)
}
else
{
let
httpResponse
=
response
as
?
HTTPURLResponse
print
(
httpResponse
)
}
}
)
dataTask
.
resume
(
)