Work with Auth0 Locally

In most cases, authenticating users through Auth0 requires an Internet connection. However, you can still develop and test apps that use Auth0 locally. In some cases, you might not need access to an Internet connection.

Please see Setting Up Multiple Environments for information on structuring your development, test, and production environments when using Auth0.

Use JSON Web Tokens (JWT) with Client-Side Applications

Because JSON Web Tokens (JWT) are stateless (that is, the app that consumes them cares only about its contents, not any of its previous states), this is one of the easiest scenarios to test locally.

You can obtain JWTs for testing using any of the following methods:

  1. Manually generate a JWT with the needed data, and sign it with your Auth0 client secret. Omit the exp claim from a token; most JWT libraries will interpret it as a token which never expires (it's possible some libraries might reject a perpetual token). This method doesn't require Internet access.

  2. Create a test user for a database connection, and programatically log this user in. Essentially, you are using the recommended process for calling an API using a highly-trusted client. For detailed implementation instructions, see Execute the Resource Owner Password Grant.

  3. Use a browser bot (e.g. Selenium) to play the role of a user, log in and retrieve a JWT. While this approach may take some effort to develop and maintain, it will allow you to test any redirection rules or MFA prompts that you have configured.

Use Sessions with Server-Side Applications

Unless your server-side application allows the generation of artificial sessions for testing, you'll need a way to perform a login through Auth0 manually.

For a high-level overview of how to do this, see Calling APIs from Server-side Web Apps. For detailed implementation instructions, see Execute an Authorization Code Grant Flow.

Log In as a User for Testing

If you need to simulate the user login process to your application, but you don't have access to a set of user credentials, you can use the impersonation endpoint to generate a link allowing you to log in as a specific user.


curl --request POST \
  --url 'https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate' \
  --header 'content-type: application/json' \
  --data '{"protocol": "PROTOCOL","impersonator_id": "IMPERSONATOR_ID", "client": "CLIENT_ID", "additionalParameters": ["response_type": "CODE","state": "STATE"]}'
var client = new RestClient("https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate");
var request = new RestRequest(Method.POST);
request.AddHeader("content-type", "application/json");
request.AddParameter("application/json", "{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io/ioutil"
)

func main() {

	url := "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate"

	payload := strings.NewReader("{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}")

	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/users/%7Buser_id%7D/impersonate")
  .header("content-type", "application/json")
  .body("{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}")
  .asString();
var settings = {
  "async": true,
  "crossDomain": true,
  "url": "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate",
  "method": "POST",
  "headers": {
    "content-type": "application/json"
  },
  "data": "{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}"
}

$.ajax(settings).done(function (response) {
  console.log(response);
});
var request = require("request");

var options = { method: 'POST',
  url: 'https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate',
  headers: { 'content-type': 'application/json' },
  body: '{"protocol": "PROTOCOL","impersonator_id": "IMPERSONATOR_ID", "client": "CLIENT_ID", "additionalParameters": ["response_type": "CODE","state": "STATE"]}' };

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" };

NSData *postData = [[NSData alloc] initWithData:[@"{"protocol": "PROTOCOL","impersonator_id": "IMPERSONATOR_ID", "client": "CLIENT_ID", "additionalParameters": ["response_type": "CODE","state": "STATE"]}" dataUsingEncoding:NSUTF8StringEncoding]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate"]
                                                       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/users/%7Buser_id%7D/impersonate",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}",
  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 = "{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}"

headers = { 'content-type': "application/json" }

conn.request("POST", "/YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'

url = URI("https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate")

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 = "{\"protocol\": \"PROTOCOL\",\"impersonator_id\": \"IMPERSONATOR_ID\", \"client\": \"CLIENT_ID\", \"additionalParameters\": [\"response_type\": \"CODE\",\"state\": \"STATE\"]}"

response = http.request(request)
puts response.read_body
import Foundation

let headers = ["content-type": "application/json"]

let postData = NSData(data: "{"protocol": "PROTOCOL","impersonator_id": "IMPERSONATOR_ID", "client": "CLIENT_ID", "additionalParameters": ["response_type": "CODE","state": "STATE"]}".dataUsingEncoding(NSUTF8StringEncoding)!)

var request = NSMutableURLRequest(URL: NSURL(string: "https://YOUR_AUTH0_DOMAIN/users/%7Buser_id%7D/impersonate")!,
                                        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()

Use Local Domains with Auth0

If you're developing your application locally, you can use localhost and other domains inaccessible by Auth0 (such as those on an intranet) as callback URLs.

Because Auth0's main identity protocol is OpenID Connect, Auth0 never needs to directly call your application's server. Instead, Auth0 redirects users to your application's endpoint(s) with required information contained in a query string or hash fragment.