FusionAuth developer image
FusionAuth developer logo
  • Back to site
  • Expert Advice
  • Blog
  • Developers
  • Downloads
  • Account
  • Contact sales
Navigate to...
  • Welcome
  • Getting Started
    • Getting Started
    • 5-Minute Setup Guide
    • Setup Wizard & First Login
    • Register a User and Login
    • Self-service Registration
    • Start and Stop FusionAuth
    • Core Concepts
      • Overview
      • Users
      • Roles
      • Groups
      • Registrations
      • Applications
      • Tenants
      • Identity Providers
      • Authentication/Authorization
      • Integration Points
    • Example Apps
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • PHP
      • Python
      • Ruby
    • Tutorials
  • Installation Guide
    • Overview
    • System Requirements
    • Server Layout
    • Cloud
    • Cluster
    • Docker
    • Fast Path
    • Kubernetes
      • Overview
      • Deployment Guide
      • Minikube Setup
      • Amazon EKS Setup
      • Google GKE Setup
      • Microsoft AKS Setup
    • Kickstart™
    • Homebrew
    • Packages
    • Database
    • FusionAuth App
    • FusionAuth Search
    • Common Configuration
  • Migration Guide
    • Overview
    • General
    • Auth0
    • Keycloak
    • Amazon Cognito
    • Firebase
    • Tutorial
  • Admin Guide
    • Overview
    • Account Portal
    • Config Management
    • Editions and Features
    • Key Rotation
    • Licensing
    • Monitoring
    • Prometheus Setup
    • Proxy Setup
    • Reference
      • Overview
      • Configuration
      • CORS
      • Data Types
      • Hosted Login Pages Cookies
      • Known Limitations
      • Password Hashes
    • Roadmap
    • Securing
    • Switch Search Engines
    • Technical Support
    • Troubleshooting
    • Upgrading
  • Login Methods
    • Identity Providers
      • Overview
      • Apple
      • Epic Games
      • External JWT
        • Overview
        • Example
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
        • Overview
        • Azure AD
        • Discord
        • Github
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • SAML v2
        • Overview
        • ADFS
      • SAML v2 IdP Initiated
        • Overview
        • Okta
      • Xbox
    • OIDC & OAuth 2.0
      • Overview
      • Endpoints
      • Tokens
    • SAML v2 IdP
      • Overview
      • Google
      • Zendesk
  • Developer Guide
    • Authentication Tokens
    • Client Libraries
      • Overview
      • Dart
      • Go
      • Java
      • JavaScript
      • .NET Core
      • Node
      • OpenAPI
      • PHP
      • Python
      • Ruby
      • Typescript
    • Events & Webhooks
      • Overview
      • Writing a Webhook
      • Securing Webhooks
      • Events
        • Overview
        • Audit Log Create
        • Event Log Create
        • JWT Public Key Update
        • JWT Refresh
        • JWT Refresh Token Revoke
        • Kickstart Success
        • User Action
        • User Bulk Create
        • User Create
        • User Create Complete
        • User Deactivate
        • User Delete
        • User Delete Complete
        • User Email Update
        • User Email Verified
        • User IdP Link
        • User IdP Unlink
        • User Login Failed
        • User Login Id Dup. Create
        • User Login Id Dup. Update
        • User Login New Device
        • User Login Success
        • User Login Suspicious
        • User Password Breach
        • User Password Reset Send
        • User Password Reset Start
        • User Password Reset Success
        • User Password Update
        • User Reactivate
        • User Reg. Create
        • User Reg. Create Complete
        • User Reg. Delete
        • User Reg. Delete Complete
        • User Registration Update
        • User Reg. Update Complete
        • User Reg. Verified
        • User 2FA Method Add
        • User 2FA Method Remove
        • User Update
        • User Update Complete
    • Guides
      • Overview
      • Advanced Registration Forms
      • Breached Password Detection
      • Multi-Factor Authentication
      • Multi-Tenant
      • Passwordless
      • Securing Your APIs
      • Silent Mode
      • Single Sign-on
    • Integrations
      • Overview
      • CleanSpeak
      • Kafka
      • Twilio
    • JSON Web Tokens
    • Key Master
    • Localization and Internationalization
    • Plugins
      • Overview
      • Writing a Plugin
      • Custom Password Hashing
    • Search And FusionAuth
    • Two Factor (pre 1.26)
    • User Control & Gating
      • Gate Unverified Users
      • Gate Unverified Registrations
      • User Account Lockout
  • Customization
    • Email & Templates
      • Overview
      • Configure Email
      • Email Templates
      • Email Variables
      • Message Templates
    • Lambdas
      • Overview
      • Apple Reconcile
      • Client Cred. JWT Populate
      • Epic Games Reconcile
      • External JWT Reconcile
      • Facebook Reconcile
      • Google Reconcile
      • HYPR Reconcile
      • JWT Populate
      • LDAP Connector Reconcile
      • LinkedIn Reconcile
      • Nintendo Reconcile
      • OpenID Connect Reconcile
      • SAML v2 Populate
      • SAML v2 Reconcile
      • SCIM Group Req. Converter
      • SCIM Group Resp. Convtr.
      • SCIM User Req. Converter
      • SCIM User Resp. Converter
      • Sony PSN Reconcile
      • Steam Reconcile
      • Twitch Reconcile
      • Twitter Reconcile
      • Xbox Reconcile
    • Messengers
      • Overview
      • Generic Messenger
      • Kafka Messenger
      • Twilio Messenger
    • Themes
      • Overview
      • Examples
      • Helpers
      • Localization
      • Template Variables
  • Premium Features
    • Advanced Threat Detection
    • Connectors
      • Overview
      • Generic Connector
      • LDAP Connector
      • FusionAuth Connector
    • Entity Management
    • SCIM
      • Overview
      • SCIM-SDK Example
    • Self Service Account Mgmt
      • Overview
      • Updating User Data & Password
      • Add Two-Factor Authenticator
      • Add Two-Factor Email
      • Add Two-Factor SMS
      • Customizing
      • Troubleshooting
  • APIs
    • Overview
    • Authentication
    • Errors
    • Actioning Users
    • API Keys
    • Applications
    • Audit Logs
    • Connectors
      • Overview
      • Generic
      • LDAP
    • Consents
    • Emails
    • Entity Management
      • Overview
      • Entities
      • Entity Types
      • Grants
    • Event Logs
    • Families
    • Forms
    • Form Fields
    • Groups
    • Identity Providers
      • Overview
      • Links
      • Apple
      • External JWT
      • Epic Games
      • Facebook
      • Google
      • HYPR
      • LinkedIn
      • Nintendo
      • OpenID Connect
      • SAML v2
      • SAML v2 IdP Initiated
      • Sony PlayStation Network
      • Steam
      • Twitch
      • Twitter
      • Xbox
    • Integrations
    • IP Access Control Lists
    • JWT
    • Keys
    • Lambdas
    • Login
    • Message Templates
    • Messengers
      • Overview
      • Generic
      • Kafka
      • Twilio
    • Multi-Factor/Two Factor
    • Passwordless
    • Reactor
    • Registrations
    • Reports
    • SCIM
      • Overview
      • SCIM EnterpriseUser
      • SCIM Group
      • SCIM Service Provider Config.
      • SCIM User
    • System
    • Tenants
    • Themes
    • Users
    • User Actions
    • User Action Reasons
    • User Comments
    • Webhooks
  • Release Notes

    JSON Web Tokens and the Login API

    Overview

    As of June 2021, this document is slightly out of date. Please see this issue for more details.

    JSON Web Tokens (or JWT for short - pronounced "jot") is a standard defined as RFC 7519 that provides a portable unit of identity. FusionAuth implements the JWT specification and can provide JWTs as part of the authentication workflows.

    After a User is authenticated via the Login API or OAuth, FusionAuth creates a JWT and returns it to the caller. This JWT will be cryptographically signed to allow other applications to verify that it was created by FusionAuth.

    If you are using OAuth grants for authentication, with the exception of the JWT signing configuration, most of this tutorial is aimed at those using the Login API directly.

    Configuring JWTs in FusionAuth

    FusionAuth provides the ability to configure a couple of aspects of its JWT handling. By navigating to Settings → Tenants in FusionAuth and selecting the JWT tab, you will see the tenant JWT configuration settings.

    The following is an example screenshot of the tenant JWT configuration.

    Global JWT Configuration

    Form Fields

    Refresh token duration Required defaults to 43200 or 30 days

    The length of time in minutes a Refresh Toke is considered valid. See Refresh Tokens below for additional information.

    JWT duration Required defaults to 60 or 1 minute

    The length of time in seconds before a JWT expires.

    Access token signing key defaults to HMAC using SHA-256

    The selected key will be used to sign the access token JWT, see Key Master settings to add or manage keys.

    • ECDSA using SHA-256 Available since 1.4.0

    • ECDSA using SHA-384 Available since 1.4.0

    • ECDSA using SHA-512 Available since 1.4.0

    • HMAC using SHA-256

    • HMAC using SHA-384

    • HMAC using SHA-512

    • RSA using SHA-256

    • RSA using SHA-384

    • RSA using SHA-512

    Id token signing key defaults to HMAC using SHA-256

    The selected key will be used to sign the Id token JWT, see Key Master settings to add or manage keys.

    • ECDSA using SHA-256 Available since 1.4.0

    • ECDSA using SHA-384 Available since 1.4.0

    • ECDSA using SHA-512 Available since 1.4.0

    • HMAC using SHA-256

    • HMAC using SHA-384

    • HMAC using SHA-512

    • RSA using SHA-256

    • RSA using SHA-384

    • RSA using SHA-512

    Configuring JWT Signing

    FusionAuth provides two levels of configuration for JWT signing, the global default values shown above, and then each Application has the option to override these default values and define their own.

    From the global JWT configuration page, you can configure the global JWT signing algorithm and keys. FusionAuth supports configurations for HMAC, ECDSA or RSA based signing algorithms.

    ECDSA & RSA Signing

    If you are using FusionAuth in a hybrid environment where some applications are trusted while others are not, ECDSA or RSA signing is preferred. This allows you to provide those applications with the public key to verify the JWT signature while securing the private key inside FusionAuth.

    This means that only one party holds the private key can is able to produce a JWTs, and it is easier to know for certain who issued and signed the JWT.

    HMAC Signing

    On the other hand, if you are in a secure environment and you require better performance, HMAC is a better solution. The downside of using HMAC signing is that each application that has access to the HMAC secret. Anyone with the secret can both produce a JWT with a valid signature and verify the signature which makes it difficult to know for certain who issued and signed the JWT.

    Application Specific Configuration

    If you navigate to Applications from the main menu, you can also configure the JWT parameters, including the signing algorithm, on a per application basis. If you don’t select to enable Application specific JWT configuration, the global algorithm configuration will be used.

    The following is an example screenshot of an Application specific JWT configuration.

    Application JWT Configuration

    Login and JWTs

    When you complete a request to the Login API, FusionAuth will return a JWT in the JSON response body as well as in an HTTP Only session cookie. The cookie has the benefit of allowing web applications to authenticate directly against FusionAuth and managing JWT identities through the browser. The cookie name that the JWT is returned in is called access_token.

    Here is an example of this Set-Cookie response header that includes a JWT with line breaks and spaces for readability.

    Example HTTP Cookie Header
    
    Set-Cookie: access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
                             eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.
                             Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo;
                             Secure; HttpOnly

    The JSON response body will also contain the JWT in an attribute called token like this:

    Example JSON Response Body with JWT
    
    {
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE0ODUxNDA5ODQsImlhdCI6MTQ4NTEzNzM4NCwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiIyOWFjMGMxOC0wYjRhLTQyY2YtODJmYy0wM2Q1NzAzMThhMWQiLCJhcHBsaWNhdGlvbklkIjoiNzkxMDM3MzQtOTdhYi00ZDFhLWFmMzctZTAwNmQwNWQyOTUyIiwicm9sZXMiOltdfQ.Mp0Pcwsz5VECK11Kf2ZZNF_SMKu5CgBeLN9ZOP04kZo",
      "user": {
        "active": true,
        "email": "example@fusionauth.io",
        "expiry": 1571786483322,
        "id": "00000000-0000-0001-0000-000000000000",
        "lastLoginInstant": 1471786483322,
        "passwordChangeRequired": false,
        "passwordLastUpdateInstant": 1471786483322,
        "verified": true
      }
    }

    Skipping JWT Creation

    There are some circumstances where you don’t need a JWT returned as part of the Login API response and therefore you can instruct FusionAuth to omit the JWT from the response. This will reduce the latency of calling the Login API because FusionAuth can skip the creation and signing of the JWT. To disable JWTs during authentication, supply the noJWT parameter in the JSON request body on the Login API.

    JWT Payload

    FusionAuth provides a few custom claims in addition to some registered claims as defined by RFC 7519 Section 4.1. The following claims will be found in a JWT issued by FusionAuth.

    Claims

    applicationId [UUID]

    The unique Id of the Application for which the User has been authenticated. A JWT can only represent authorization to a single Application.

    This claim is only present if the User has a registration to the Application.

    To obtain a JWT for another Application you must either authenticate again with a different applicationId using the Authentication API or utilize the Issue a JWT API to exchange a valid JWT for another.

    aud [String]

    The audience the JWT is intended for. This registered claim is defined by RFC 7519 Section 4.1.3

    This claim will be equal to the client_id.

    authenticationType [String]

    The method used to authenticate the User which resulted in this JWT being generated. The possible values are:

    • APPLE - The User was authenticated using Apple. Available since 1.17.0

    • APPLICATION_TOKEN - The User was authenticated using an Application Authentication Token.

    • FACEBOOK - The User was authenticated using Facebook.   Available since 1.1.0

    • FEDERATED_JWT - The User was authenticated using a JWT from an external Identity Provider.

    • GENERIC_CONNECTOR - The user was authenticated using a generic connector.   Available since 1.18.0

    • GOOGLE - The User was authenticated using Google. Available since 1.1.0

    • HYPR - The User was authenticated using HYPR provider. Available since 1.12.0

    • JWT_SSO - A valid JWT authorized to one Application was exchanged for another JWT authorized to a different Application.

    • LDAP_CONNECTOR - The user was authenticated using an LDAP connector.   Available since 1.18.0

    • LINKEDIN - The user was authenticated using LinkedIn.   Available since 1.23.0

    • ONE_TIME_PASSWORD The User was authenticated using a one time password.   Available since 1.5.0

    • OPENID_CONNECT - The User was authenticated using an external OpenID Connect provider. Available since 1.1.0

    • PASSWORD - The User was authenticated using a loginId and password combination.

    • PASSWORDLESS - The user was authenticated using a passwordless login link.   Available since 1.5.0

    • PING - The user was authenticated using the PING API w/ a valid JWT.

    • REGISTRATION - The user was created using the Registration API.   Available since 1.16.0

    • REFRESH_TOKEN - The User requested a new JWT using a Refresh Token.

    • SAMLv2 - The User was authenticated using an external SAMLv2 provider. Available since 1.6.0

    • TWITTER - The User was authenticated using Twitter. Available since 1.1.0

    • USER_CREATE - The user was created using the User API.   Available since 1.16.0

    email [String]

    The email address of the User whose claims are represented by this JWT.

    email_verified [Boolean]

    The OpenId Connect claim indicating if the User’s email has been verified.

    exp [Long]

    The expiration instant of the JWT expressed as UNIX time which is the number of seconds since Epoch. This registered claim is defined by RFC 7519 Section 4.1.4

    iat [Long]

    The instant that the JWT was issued expressed as UNIX time which is the number of seconds since Epoch. This registered claim is defined by RFC 7519 Section 4.1.6

    iss [String]

    The issuer of the JWT. For FusionAuth, this is always the value defined in the global JWT configuration. This registered claim is defined by RFC 7519 Section 4.1.1

    preferred_username [String] Available since 1.5.0

    The username of the User who claims are represented by this JWT.

    roles [Array<String>]

    The roles assigned to the User in the authenticated Application. This claim is only present if the User has a registration to the Application.

    sub [UUID]

    The subject of the access token. This value is equal to the User’s unique Id in FusionAuth. This registered claim is defined by RFC 7519 Section 4.1.2

    Example JWT

    Here is an example JWT that might be returned from FusionAuth:

    Example JWT
    
    {
      "applicationId": "469b0ba1-a849-4603-883e-3b05c0d2b7ce",
      "aud": "469b0ba1-a849-4603-883e-3b05c0d2b7ce",
      "authenticationType": "PASSWORD",
      "email": "richard@fusionauth.io",
      "exp": 1504112919754,
      "iat": 1504103919754,
      "iss": "acme.com",
      "roles": [
        "role 1",
        "role 2"
      ],
      "sub": "6558c73f-b345-4917-9aac-0feab21eeeeb"
    }

    Refresh Tokens

    Refresh tokens are a method of allowing a User to stay logged into an Application for a long period of time without requiring them to type in their password. This method is often used by Applications that don’t store sensitive data such as games and social networks. FusionAuth provides refresh tokens in the response from the Login API provided that you supply these elements:

    • loginId - the User’s login Id

    • password - the User’s password or Authentication Token

    • applicationId - the identifier for the Application the user is logging into

    If all of these attributes are supplied to the Login API then FusionAuth will produce a refresh token. The refresh token will be returned in the JSON in the response body as well as in a in a cookie header. The refresh token will be in a parameter called refreshToken in the JSON response and the HTTP Only persistent cookie will be named refresh_token.

    You will also need to verify that you have enabled Refresh Tokens for the application. Using the FusionAuth UI, navigate to Settings → Applications → Security Tab. Here you will find the Login API settings. Verify this application is configured to generate and use refresh tokens.

    Here is an example of this Set-Cookie response header for a refresh token.

    Example HTTP Cookie Header
    
    Set-Cookie: refresh_token=eu1SsrjsiDf3h3LryUjxHIKTS0yyrbiPcsKF3HDp; Max-Age=2592000; Expires=Fri, 29-Sep-2017 15:20:24 GMT; Secure; HttpOnly

    Here is an example of the JSON response body that contains the refresh token:

    Example JSON with Refresh Token
    
    {
      "refreshToken": "eu1SsrjsiDf3h3LryUjxHIKTS0yyrbiPcsKF3HDp",
      "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MDQxMDY0ODQsImlhdCI6MTUwNDEwNjQyNCwiaXNzIjoiaW52ZXJzb2Z0LmNvbSIsInN1YiI6ImUzMDIzMmZiLTIxN2EtNDllYi1iN2QxLTI5YzhhNWVmZmM1YiIsImFwcGxpY2F0aW9uSWQiOiIzYzIxOWU1OC1lZDBlLTRiMTgtYWQ0OC1mNGY5Mjc5M2FlMzIiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsInJvbGVzIjpbImFkbWluIl19.eNF4F0iT8qUtyr3kb_-RSM-jibaP0w-419sD94N3Gkk",
      "user": {
        "active": true,
        "email": "example@fusionauth.io",
        "expiry": 1571786483322,
        "id": "00000000-0000-0001-0000-000000000000",
        "lastLoginInstant": 1471786483322,
        "passwordChangeRequired": false,
        "passwordLastUpdateInstant": 1471786483322,
        "verified": true
      }
    }

    Note: Refresh Tokens are considered sensitive information. The token must be secured on the User’s device. If a Refresh Token is compromised, the token bearer may perform authenticated requests on behalf of the User.

    Once you have a refresh token on the device, you can call the Refresh a JWT API to get a new JWT from FusionAuth using the refresh token. Using this pattern allows you to perform authenticated actions using the JWT without prompting the User to authenticate as long as the refresh token is active.

    Feedback

    How helpful was this page?

    See a problem?

    File an issue in our docs repo

    © 2022 FusionAuth
    Subscribe for developer updates