All pages
Powered by GitBook
1 of 1

Refresh Token

Learn about refresh token, how to get a refresh token and how to use it to get a new access token.

In Authgear, a refresh token is a key that our authorization server returns when an OAuth 2.0 client application successfully exchanges an authorization code for an access token. Usually, in OAuth 2.0, access tokens expire after some time (you can configure this time in the Authgear portal). The refresh token exists to allow your application to request a new access token after the previous one has expired. It eliminates the need for your user to repeat the entire login process all over.

In this post, we'll teach you how to get a refresh token and how to use it to request a new access token after the old one has expired.

Pre-requisite

  • This post assumes you already have some experience with using Authgear as an OIDC provider.

  • Have the configuration (client ID, authorized redirect URI, endpoints, etc) of your Authgear application noted down.

How to Get A Refresh Token

There are many ways to implement Authgear as an Open ID Connect (OIDC) provider for your application based on the programming language or framework you're using. This may determine the procedure you follow to get a refresh token. For example, if you're using any of our official SDKs, there are built-in methods and configurations that simplify the process of getting a refresh token and renewing an expired access token.

However, the key thing that all implementations have in common is including the following scope parameter to your application authorization URL:

Or just scope=offline_access.

Example of Authgear token endpoint response with refresh token included:

  • The refresh_token field contains the refresh token.

  • expires_in is how long (seconds) an access token is valid before it expires.

The following steps show an example of how to get a refresh token from Authgear with some common languages and frameworks.

Step 1: Add Authgear Configuration to Your Code

For this step, log in to the Authgear Portal, navigate to the Applications section, and select your application. copy the configuration details for your application into your code as shown below:

For this React example, we are using the official Authgear JavaScript SDK. Install it using the following command:

Because the SDK can handle the task of getting a refresh token and using it to renew an access token, you do not need to specify the offline scope in your configuration.

For this PHP example, we use the League OAuth 2.0 client PHP package. Install the package using the following command:

composer require league/oauth2-client

Then configure your application like this:

<?php
require 'vendor/autoload.php';
session_start(); 

$appUrl = "https://your_project.authgear.cloud";
$clientID = "";
$clientSecret = "";
$redirectUri = "http://localhost:8081/";

$provider = new \League\OAuth2\Client\Provider\GenericProvider([
    'clientId'                => $clientID,    // The client ID assigned to you by the provider
    'clientSecret'            => $clientSecret,    // The client password assigned to you by the provider
    'redirectUri'             => $redirectUri,
    'urlAuthorize'            => $appUrl . '/oauth2/authorize',
    'urlAccessToken'          => $appUrl . '/oauth2/token',
    'urlResourceOwnerDetails' => $appUrl . '/oauth2/userInfo',
    'scopes' => 'openid offline_access'
]);

Notice the line with 'scopes' => 'openid offline_access', the offline_access scope is required for Authgear to return a refresh token.

For this example, we're using Node.js, and creating a simple Express application that makes HTTP requests to the Authgear server. Run the following commands to install the required Node package to run the code:

1. Express:

npm install express

2. Axios:

npm install axios

Now configure Authgear in your Express application like this:

const express = require('express');
const axios = require('axios');

const app = express();
const port = process.env.PORT || 3000;

const config = {
  client: {
    id: "CLIENT_ID",
    secret: "CLIENT_SECRET",
    redirect_url: "REDIRECT_URL"
  },
  auth: {
    tokenHost: "AUTHGEAR_ENDPOINT",
    tokenPath: '/oauth2/token',
    authorizePath: '/oauth2/authorize',
    scope: 'openid+offline_access'
  },
};

The value in config.auth.scope includes the offline_access scope required for Authgear to return a refresh token when your application makes a call to the token endpoint.

Step 2: Get Refresh Token From Token Endpoint

Authgear will return the refresh token along with the access token when your application makes an HTTP request to the /oauth2/token endpoint, provided you include the offline_access scope as shown in step 1.

Note: Authgear will omit refresh token if your initial request to the authorize URL does not include the offline_access scope.

The following code examples show how to make a request to the token endpoint and get the refresh token from the response JSON object.

As mentioned earlier the Authgear JavaScript SDK can handle the task of getting the refresh token and using it to renew the access token when necessary. The following code shows how to call the method:

authgear
    .refreshAccessTokenIfNeeded()
    .then(() => {
        // access token is ready to use
        // accessToken can be string or undefined
        // it will be empty if user is not logged in or session is invalid
        const accessToken = authgear.accessToken;

        // include Authorization header in your application request
        const headers = {
            Authorization: `Bearer ${accessToken}`
        };
    });

While using the League OAuth client, you can get the refresh token returned by the token endpoint by calling the getRefreshToken() method on the object returned by the provider->getAccessToken(). The following code shows the flow for starting an authorization request, exchanging the authorization code for an access token, and getting the refresh token:

if (!isset($_GET['code'])) {
    // Fetch the authorization URL from the provider; this returns the
    // urlAuthorize option and generates and applies any necessary parameters
    // (e.g. state).
    $authorizationUrl = $provider->getAuthorizationUrl();

    // Get the state generated for you and store it to the session.
    $_SESSION['oauth2state'] = $provider->getState();

    // Redirect the user to the authorization URL.
    header('Location: ' . $authorizationUrl);
    exit;
}
else {
    $code = $_GET['code'];

    if (empty($_GET['state']) || empty($_SESSION['oauth2state']) || $_GET['state'] !== $_SESSION['oauth2state']) {
        if (isset($_SESSION['oauth2state'])) {
            unset($_SESSION['oauth2state']);
        }

        exit('Invalid state');
    } else {
        try {
            $accessToken = $provider->getAccessToken('authorization_code', [
                'code' => $code
            ]);
            
            //Get refresh token
            $refreshToken = $accessToken->getRefreshToken();
            echo "Login successful access token:". $accessToken;
            echo " Refresh token:". $refreshToken;
            
        } catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
            // Failed to get the access token or user details.
            exit($e->getMessage());
        }
    }
}

To get the refresh token in this Express example, simply send an HTTP request to the token endpoint to exchange the authorization for an access token. The refresh token will be in the response for the endpoint under a refresh_token field. The following code shows the example for reading the value of the refresh_token field in an express app:

const data = {
  client_id: config.client.id,
  client_secret: config.client.secret,
  code: req.query.code,
  grant_type: 'authorization_code',
  response_type: 'code',
  redirect_uri: config.client.redirect_url,
  scope: config.auth.scope
};

try {
  const getToken = await axios.post(`
    ${config.auth.tokenHost}${config.auth.tokenPath}`,
    data,
    {
    headers: { "Content-Type": "application/x-www-form-urlencoded" }
    }
  );

  const accessToken = getToken.data.access_token;
  const refreshToken = getToken.data.refresh_token;
  res.send(`
  <p>${JSON.stringify(getToken.data)}</p>
    <div style="max-width: 650px; margin: 16px auto; background-color: #EDEDED; padding: 16px;">
      <p>Welcome</p>
      <p>Refresh token: ${refreshToken}</p>
      
    </div>
`);
} catch (error) {
  res.send("An error occurred! Login could not complete. Error data: " + error);
}

Summary

To get a refresh token from Authgear, you need to include offline_access in your authorization request.

The Authgear SDKs take care of getting refresh token and you do not need to do any extra configuration.

It is recommended to store the refresh token securely on the user's device and use it to request a new access token when the current one expires.