Authentication for Server-side Web Apps

Versioncurrent

You can use the Auth0 Authentication API to create server-side web applications that uses OAuth 2.0 and OpenID Connect to authenticate users and get their authorization to access protected resources.

Overview

Auth0 exposes endpoints that you can use to authenticate users and get their authorization.

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 a pre-configured callback URL, returning an authorization code in the query string parameters of the callback URL. This code can then be exchanged for an ID Token (which contains information about the identity of the user) and an Access Token.

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 a 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 regarding the user, such as the user's name, email address, profile picture and so on. These attributes are referred to as Claims and they can be extracted from the ID Token and used in your application (for example, to display a user's name and profile image).

You will also receive an Access Token which you can use to call the Authentication API's /userinfo endpoint or your own APIs. For more information on calling APIs web apps running on the server, see Calling APIs from Server-side Web Apps

Authentication flow for server-side web apps

  1. The Application initiates the flow and redirects the user to the Authorization Server.
  2. The user authenticates.
  3. The Authorization Server redirects to the redirect_uri with a code in the query string.
  4. The Application sends the code together with the Client ID, Client Secret and redirect_uri to the Authorization Server.
  5. 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.

Next, click on Show Advanced Settings. Go to the OAuth tab and ensure that you have enabled the OIDC Conformant switch:

Save the Settings.

Call the Authorization URL

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. 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 get an ID Token in the response, you need to specify at least the scope of openid in the request. If you want to return the user's full profile information, you can request openid profile.

You can read the scopes documentation for more information.
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.

Be sure to add the redirect_uri URL to the list of Allowed Callback URLs in the Settings tab of your Application inside the Auth0 Dashboard.

Exchange the 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 a code as a query string parameter of the URL, such as

https://YOUR_APP/callback?code=tQPUv...

You application will need to handle the request to this callback URL, extract the code query string parameter and call the /oauth/token endpoint of the Auth0 Authentication API in order to exchange the 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 access_token, expires_in, id_token and token_type values (and also potentially a refresh_token), for example:

{
  "access_token": "subBe48...",
  "expires_in": 86400,
  "id_token": "eyJ0eXAi...",
  "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.
email 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.

The JWT.io website has a handy debugger which will allow you to debug any JSON Web Token. This is useful is you quickly want to decode a JWT to see the information contained in the token.

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
  &scope=openid

After the user has authenticated, they will be redirected back to the redirect_uri with a code query string parameter:

https://YOUR_APP/callback?code=2OKj...

You can then exchange the 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 profile information, for example their name and profile picture, by requesting the profile scope in addition to the openid scope:

https://YOUR_AUTH0_DOMAIN/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://YOUR_APP/callback
  &scope=openid%20profile

After the user has authenticated, they will be redirected back to the redirect_uri with a code query string parameter:

https://YOUR_APP/callback?code=2OKj...

You can then exchange the code for an ID Token. The profile attributes of the user, such as 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:

https://YOUR_AUTH0_DOMAIN/authorize
  ?response_type=code
  &client_id=YOUR_CLIENT_ID
  &redirect_uri=https://YOUR_APP/callback
  &scope=openid%20profile
  &connection=github

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 a code query string parameter:

https://YOUR_APP/callback?code=2OKj...

You can then exchange the code for an ID Token. Since we also requested the profile scope, the user's Github profile attributes will also be available. In the example below you will notice the name, nickname and picture attributes are returned with the values from GitHub. You will also notice that the sub claim contains the User's unique ID returned from GitHub:

{
  "name": "Jerrie Pelser",
  "nickname": "jerriep",
  "picture": "https://avatars.githubusercontent.com/u/1006420?v=3",
  "iss": "https://auth0pnp.auth0.com/",
  "sub": "github|100...",
  "aud": "xvt...",
  "exp": 1478114742,
  "iat": 1478078742
}