Validating JWTs Offline

Descope employs JSON Web Token (JWT) to ensure secure authentication, and authorization.

In web applications, it's essential to parse and validate these tokens to guarantee their integrity and authenticity.

Here's how to use Descope's backend SDKs to validate JWTs:

Backend SDK

Install SDK

Terminal
npm i --save @descope/node-sdk

Import and initialize SDK

import DescopeClient from '@descope/node-sdk';
try{
    //  baseUrl="<URL>" // When initializing the Descope client, you can also configure the baseUrl ex: https://auth.company.com  - this is useful when you utilize a custom domain within your Descope project.
    const descopeClient = DescopeClient({ projectId: '__ProjectID__' });
} catch (error) {
    // handle the error
    console.log("failed to initialize: " + error)
}

Call the Validate JWT Function

After passing in the JWT from the frontend to your backend, you can simply call the validate JWT function.

You can optionally validate the aud claim by passing an audience parameter to prevent token reuse across applications. The parameter accepts either a string or an array of strings.

Note: Not all SDKs support audience validation - see code examples below for supported SDKs.

// Args:
//   sessionToken (str): The session token, which contains the signature that will be validated
const sessionToken = "xxxx"; // extract from request authorization header

try {
  // Basic validation without audience checking
  const authInfo = await descopeSdk.validateSession(sessionToken);
  
  // Or validate with a single audience (string)
  const authInfoWithAudience = await descopeSdk.validateSession(sessionToken, {
    audience: '__ProjectID__'
  });
  
  // Or validate with multiple audiences (array)
  const authInfoWithMultipleAudiences = await descopeSdk.validateSession(sessionToken, {
    audience: ['__ProjectID__', 'my-custom-audience']
  });
  
  console.log("Successfully validated user session:");
  console.log(authInfo);
} catch (error) {
  console.log("Could not validate user session " + error);
}

Configuring JWT Validation Leeway

Note

Currently JWT validation leeway is only configurable in the Go and Python SDKs.

When validating JWTs, the SDK accounts for minor clock differences (time skew) between the systems that issued and validate the token. By default, the SDK applies a 5-second leeway to the time-based claims (such as exp, nbf, and iat), so small clock drifts between servers do not cause otherwise-valid tokens to be rejected.

If your systems experience larger clock differences, you can increase the leeway when initializing the SDK.

import "github.com/descope/go-sdk/descope/client"
import "time"

// JWTLeeway (optional, defaults to 5 seconds) sets the acceptable time skew (leeway)
// applied to JWT time-based claims during validation.
descopeClient, err := client.NewWithConfig(&client.Config{
    ProjectID: "__ProjectID__",
    JWTLeeway: 30 * time.Second, // Increase leeway to handle larger clock differences
})
if err != nil {
    // handle the error
    log.Println("failed to initialize: " + err.Error())
}

Offline

Validating JSON Web Tokens (JWTs) offline is crucial in situations where the server running the SDK does not have access to the internet. Descope SDKs allow you to handle this scenario with ease. This article explains how to validate JWTs offline by providing a custom public key.

Providing a Custom Public Key

Finding Your Public Key

Your public key can be located at https://api.descope.com/v2/keys/__ProjectID__ for US-based projects. Use the localized baseURL for projects located outside of the US. Refer to the Descope Documentation and API reference page for additional details on locating and handling public keys.

Initializing the SDK with a Custom Public Key

To provide your own public key, you can do so by including the publicKey option when initializing the SDK. The public key must be a JSON object containing the appropriate algorithm and other details. Below are examples of initializing the SDK with a public key.

import DescopeClient from '@descope/node-sdk';
try{
    //  baseUrl="<URL>" // When initializing the Descope clientyou can also configure the baseUrl ex: https://auth.company.com  - this is useful when you utilize a custom domain within your Descope project.
    const descopeClient = DescopeClient({ projectId: '__ProjectID__', publicKey: '{"alg":"RS256", ... }'});
} catch (error) {
    // handle the error
    console.log("failed to initialize: " + error)
}

Conclusion

Validating JWTs offline via SDK by providing a custom public key enhances security and functionality, especially when working in environments without internet access.

If you have any other questions about Descope, feel free to reach out to us!

Was this helpful?

On this page