You can use the Auth0 Authentication API to create server-side web applications that uses OAuth 2.0 authorization to authenticate users.
Overview
Auth0 exposes OAuth 2.0 endpoints for authenticating any user. You can redirect the user from your web application to these endpoints in the web browser. Auth0 will handle the authentication of the user, and then redirect the user back to the redirect_uri
(also referred to as the Callback URL), returning an authorization_code
in the query string parameters of the Callback URL. This authorization_code
can then be exchanged for an id_token
which contains the identity of the user.
The Authentication Flow
The OAuth 2.0 Authorization Framework allows for different kinds of authorization flows (called Grant Types) depending on the type of application. The flow used for Server-side Web applications is known as the Authorization Code flow.
The Authorization Code flow is initiated by redirecting the user in the web browser to the Auth0 /authorize
endpoint. Auth0 will then display the Auth0 Lock dialog, allowing the user to enter their credentials or alternatively sign in with any other configured Identity Provider.
After the user has authenticated, Auth0 will redirect the browser back to the Redirect URI (also called Callback URL), passing along an authorization_code
parameter in the query string of the Callback URL. This code can then be exchanged for an id_token
by making a request to the /oauth/token
endpoint.
The id_token
is a JSON Web Token (JWT) and contains various attributes - referred to as Claims - regarding the user, such as the user's name, email address, profile picture and so on.. The id_token
can be decoded to extract the claims and you are free to use these inside of your application, to display a user's name and profile image for example.
- The Application initiates the flow and redirects the user to the Authorization Server.
- The user authenticates.
- The Authorization Server redirects to the
redirect_uri
with anauthorization_code
in the query string. - The Application sends the
authorization_code
together with theredirect_uri
and the Client Id/Client Secret to the Authorization Server. - The Authorization Server validates this information and returns an
id_token
.
Register your Application
The first thing you need to do is to create a new application in Auth0. An Auth0 application maps to your application and allows it to use Auth0 for authentication.
Navigate to the Auth0 Dashboard and click on the Applications menu option on the left. Create a new Application by clicking on the Create Application button.
The Create Application window will open, allowing you to enter the name of your new application. Choose Regular Web Applications as the Application Type and click on the Create button to create the new application.
Once the application has been created you can navigate to the Settings tab of the application and in the Allowed Callback URLs field add a URL where Auth0 must redirect to after the user has authenticated, such as https://YOUR_APP/callback
.
This URL must be part of your application, as your application will need to retrieve the code
and exchange it for the id_token
.
The URL used when authenticating a user is https://YOUR_AUTH0_DOMAIN/authorize
. This is the initial endpoint to which a user must be redirected. This will handle checking whether any SSO session is active, authenticating the user and also potentially redirect the user directly to any Identity Provider to handle authentication.
This endpoint supports the following query string parameters:
Parameter | Description |
---|---|
response_type | The response type specifies the Grant Type you want to use. This can be either code or token . For server-side web applications using the Authorization Code Flow this must be set to code |
client_id | The Client ID of the Application you registered in Auth0. This can be found on the Settings tab of your Application in the Auth0 Dashboard |
scope | Specifies the claims (or attributes) of the user you want the be returned in the id_token . To obtain an id_token you need to specify at least a scope of openid (if no scope is specified then openid is implied). You can also request other scopes, so for example to return the user's name and profile picture you can request a scope of openid name picture .You can read up more about scopes. |
redirect_uri | The URL in your application where the user will be redirected to after they have authenticated, such as https://YOUR_APP/callback |
connection | This is an optional parameter which allows you to force the user to sign in with a specific connection. You can for example pass a value of github to send the user directly to GitHub to log in with their GitHub account.If this parameter is not specified the user will be presented with the normal Auth0 Lock screen from where they can sign in with any of the available connections. You can see the list of configured connections on the Connections tab of your application. |
state | The state parameter will be sent back should be used for CSRF and contextual information (like a return url) |
Exhange the access_code
for an id_token
After the user has authenticated, Auth0 will call back to the URL specified in the redirect_uri
query string parameter which was passed to the /authorize
endpoint. When calling back to this URL, Auth0 will pass along an access_token
in the code
query string parameter of the URL, such as
https://YOUR_APP/callback?code=2OKj...
You application will need to handle the request to this callback URL, extract the access_code
from the code
query string parameter and call the /oauth/token
endpoint of the Auth0 Authentication API in order to exchange the access_code
for the id_token
:
curl --request POST \
--url 'https://YOUR_AUTH0_DOMAIN/oauth/token' \
--header 'content-type: application/json' \
--data '{"grant_type":"authorization_code","client_id": "YOUR_CLIENT_ID","client_secret": "YOUR_CLIENT_SECRET","code": "YOUR_AUTHORIZATION_CODE","redirect_uri": "https://YOUR_APP/callback"}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/oauth/token");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main
import (
"fmt"
"strings"
"net/http"
"io/ioutil"
)
func main() {
url := "https://YOUR_AUTH0_DOMAIN/oauth/token"
payload := strings.NewReader("{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("content-type", "application/json")
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.post("https://YOUR_AUTH0_DOMAIN/oauth/token")
.header("content-type", "application/json")
.body("{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}")
.asString();
var settings = {
"async": true,
"crossDomain": true,
"url": "https://YOUR_AUTH0_DOMAIN/oauth/token",
"method": "POST",
"headers": {
"content-type": "application/json"
},
"processData": false,
"data": "{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}"
}
$.ajax(settings).done(function (response) {
console.log(response);
});
var request = require("request");
var options = { method: 'POST',
url: 'https://YOUR_AUTH0_DOMAIN/oauth/token',
headers: { 'content-type': 'application/json' },
body:
{ grant_type: 'authorization_code',
client_id: 'YOUR_CLIENT_ID',
client_secret: 'YOUR_CLIENT_SECRET',
code: 'YOUR_AUTHORIZATION_CODE',
redirect_uri: 'https://YOUR_APP/callback' },
json: true };
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});
#import <Foundation/Foundation.h>
NSDictionary *headers = @{ @"content-type": @"application/json" };
NSDictionary *parameters = @{ @"grant_type": @"authorization_code",
@"client_id": @"YOUR_CLIENT_ID",
@"client_secret": @"YOUR_CLIENT_SECRET",
@"code": @"YOUR_AUTHORIZATION_CODE",
@"redirect_uri": @"https://YOUR_APP/callback" };
NSData *postData = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/oauth/token"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:10.0];
[request setHTTPMethod:@"POST"];
[request setAllHTTPHeaderFields:headers];
[request setHTTPBody:postData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (error) {
NSLog(@"%@", error);
} else {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
NSLog(@"%@", httpResponse);
}
}];
[dataTask resume];
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://YOUR_AUTH0_DOMAIN/oauth/token",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => "{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}",
CURLOPT_HTTPHEADER => array(
"content-type: application/json"
),
));
$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.HTTPSConnection("")
payload = "{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}"
headers = { 'content-type': "application/json" }
conn.request("POST", "/YOUR_AUTH0_DOMAIN/oauth/token", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))
require 'uri'
require 'net/http'
url = URI("https://YOUR_AUTH0_DOMAIN/oauth/token")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
request = Net::HTTP::Post.new(url)
request["content-type"] = 'application/json'
request.body = "{\"grant_type\":\"authorization_code\",\"client_id\": \"YOUR_CLIENT_ID\",\"client_secret\": \"YOUR_CLIENT_SECRET\",\"code\": \"YOUR_AUTHORIZATION_CODE\",\"redirect_uri\": \"https://YOUR_APP/callback\"}"
response = http.request(request)
puts response.read_body
import Foundation
let headers = ["content-type": "application/json"]
let parameters = [
"grant_type": "authorization_code",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"code": "YOUR_AUTHORIZATION_CODE",
"redirect_uri": "https://YOUR_APP/callback"
]
let postData = NSJSONSerialization.dataWithJSONObject(parameters, options: nil, error: nil)
var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/oauth/token")!,
cachePolicy: .UseProtocolCachePolicy,
timeoutInterval: 10.0)
request.HTTPMethod = "POST"
request.allHTTPHeaderFields = headers
request.HTTPBody = postData
let session = NSURLSession.sharedSession()
let dataTask = session.dataTaskWithRequest(request, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
println(error)
} else {
let httpResponse = response as? NSHTTPURLResponse
println(httpResponse)
}
})
dataTask.resume()
The response from /oauth/token
contains an access_token
, id_token
and token_type
values (and also potentially a refresh_token
), for example:
{
"access_token": "AP16...",
"id_token": "eyJ0...",
"token_type": "Bearer"
}
The token_type
will be set to Bearer and the id_token
will be a JSON Web Token (JWT) containing information about the user. You will need to decode the id_token
in order to read the claims (or attributes) of the user. The JWT section of our website contains more information about the structure of a JWT.
You can refer to the libraries section on the JWT.io website in order to obtain a library for your programming language of choice which will assist you in decoding the id_token
.
Once the JWT is decoded, you can extract the information about the user from the Payload of the id_token
. This is a JSON structure and will contain the claims (attributes) about the user as well as some other metadata.
The id_token
Payload
An example payload for an id_token
may look something like this:
{
"name": "Jerrie Pelser",
"email": "jerrie@j...",
"picture": "https://s.gravatar.com/avatar/6222081fd7dcea7dfb193788d138c457?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fje.png",
"iss": "https://auth0pnp.auth0.com/",
"sub": "auth0|581...",
"aud": "xvt...",
"exp": 1478113129,
"iat": 1478077129
}
The payload above contains the following claims:
Parameter | Description |
---|---|
name | The name of the user which is returned from the Identity Provider. |
The email address of the user which is returned from the Identity Provider. | |
picture | The profile picture of the user which is returned from the Identity Provider. |
sub | The unique identifier of the user. This is guaranteed to be unique per user and will be in the format (identity provider)|(unique id in the provider), such as github|1234567890. |
iss | The issuer. A case-sensitive string or URI that uniquely identifies the party that issued the JWT. For an Auth0 issued id_token , this will be the URL of your Auth0 tenant.This is a registered claim according to the JWT Specification |
aud | The audience. Either a single case-sensitive string or URI or an array of such values that uniquely identify the intended recipients of this JWT. For an Auth0 issued id_token , this will be the Client ID of your Auth0 Application.This is a registered claim according to the JWT Specification |
exp | The expiration time. A number representing a specific date and time in the format “seconds since epoch” as defined by POSIX6. This claim sets the exact moment from which this JWT is considered invalid. This is a registered claim according to the JWT Specification |
iat | The issued at time. A number representing a specific date and time (in the same format as exp ) at which this JWT was issued.This is a registered claim according to the JWT Specification |
The exact claims contained in the id_token
will depend on the scope
parameter you sent to the /authorize
endpoint. In an id_token
issued by Auth0, the registered claims and the sub
claim will always be present, but the other claims depends on the scope
. You can refer to the examples below to see examples of how the scope influences the claims being returned.
Keep the user logged in
Auth0 will assist you in authenticating a user, but it is up to you to keep track in your application of whether or not a user is logged in. You can use a cookie or other session storage to keep track of whether a user is logged in or not, and also to store the claims of the user which was extracted from the id_token
.
You can then use those claims inside of your application to display the user's information or otherwise personalize the user's experience.
Examples
A Basic Authentication Request
The following is the most basic request you can make to the /authorize
endpoint. It will display the Lock screen and allow a user to sign in with any of the configured connections.
https://YOUR_AUTH0_DOMAIN/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
After the user has authenticated, they will be redirected back to the redirect_uri
with the access_code
in the code
query string parameter:
https://YOUR_APP/callback?code=2OKj...
You can then exchange the access_code
for an id_token
. This is an example of the decoded payload of the id_token
which will be returned:
{
"iss": "https://auth0pnp.auth0.com/",
"sub": "auth0|581...",
"aud": "xvt9...",
"exp": 1478112929,
"iat": 1478076929
}
Request the Name and Profile Picture
You can request a user's name and profile picture by requesting the name
and picture
scopes.
https://YOUR_AUTH0_DOMAIN/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
&scope=openid%20name%20picture
After the user has authenticated, they will be redirected back to the redirect_uri
with the access_code
in the code
query string parameter:
https://YOUR_APP/callback?code=2OKj...
You can then exchange the access_code
for an id_token
. The name and profile picture will be available in the name
and picture
claims of the returned id_token
:
{
"name": "jerrie@...",
"picture": "https://s.gravatar.com/avatar/6222081fd7dcea7dfb193788d138c457?s=480&r=pg&d=https%3A%2F%2Fcdn.auth0.com%2Favatars%2Fje.png",
"iss": "https://auth0pnp.auth0.com/",
"sub": "auth0|581...",
"aud": "xvt...",
"exp": 1478113129,
"iat": 1478077129
}
Request a User Log In With GitHub
You can send a user directly to the GitHub authentication screen by passing the value of github to the connection
parameter. Note that we also request the openid
, name
, picture
and email
scopes:
https://YOUR_AUTH0_DOMAIN/authorize
?response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https://YOUR_APP/callback
&scope=openid%20name%20picture%20email
&connection=github
Log in with other social providers
You can just as easily request a user log in with other social providers, like Google or Facebook. All you have to do is configure the corresponding connection in the dashboard and change the connection
value of this call to /authorize
with the name of the connection to use (google-oauth2
for Google, facebook
for Facebook, and so forth). You can get the connection's name from the Settings of the connection in the dashboard. For more info:
After the user has authenticated, they will be redirected back to the redirect_uri
with the id_token
and token_type
passed as parameters in the hash fragment:
After the user has authenticated, they will be redirected back to the redirect_uri
with the access_code
in the code
query string parameter:
https://YOUR_APP/callback?code=2OKj...
You can then exchange the access_code
for an id_token
. The user's name and profile picture and email address will be available in the name
, picture
and email
claims of the returned id_token
. You will also notice that the sub
claim contains the User's unique ID returned from GitHub:
{
"name": "Jerrie Pelser",
"picture": "https://avatars.githubusercontent.com/u/1006420?v=3",
"email": "jerrie@...",
"email_verified": true,
"iss": "https://auth0pnp.auth0.com/",
"sub": "github|100...",
"aud": "xvt...",
"exp": 1478114742,
"iat": 1478078742
}