Docs

JWT

The JWT plugin provides endpoints to retrieve a JWT token and a JWKS endpoint to verify the token.

This plugin is not meant as a replacement for the session. It's meant to be used for services that can't use the session.

Installation

Add the plugin to your auth config

auth.ts
import { betterAuth } from "better-auth"
import { jwt, bearer } from "better-auth/plugins"
 
export const auth = betterAuth({
    plugins: [ 
        jwt(), 
        bearer() //this allows you to pass the session as a bearer token
    ] 
})

Migrate the database

Run the migration or generate the schema to add the necessary fields and tables to the database.

npx @better-auth/cli migrate

See the Schema section to add the fields manually.

Usage

Once you've installed the plugin, you can start using the JWT & JWKS plugin to get the token and the JWKS through their respective endpoints.

JWT

Retrieve the token

To get the token, call the /token, this will return the following:

  { 
    "token": "ey..."
  }

Make sure to include the token in the Authorization header of your requests.

await fetch("/api/auth/token", {
  headers: {
    "Authorization": `Bearer ${token}`
  },
})

Verifying the token

The token can be verified in your own service, without the need for an additional verify call or database check. For this JWKS is used, the public key can be fetched from the /jwks endpoint.

Since this key is not subject to a frequent change, it can be cached indefinitely. The Key ID (kid) that was used to sign a JWT is included in the header of the token. In the case a JWT with a different kid is received it is recommended to fetch the JWKS again.

  {
    "keys": [
        {
            "crv": "Ed25519",
            "x": "bDHiLTt7u-VIU7rfmcltcFhaHKLVvWFy-_csKZARUEU",
            "kty": "OKP",
            "kid": "c5c7995d-0037-4553-8aee-b5b620b89b23"
        }
    ]
  }

Schema

The JWT plugin adds the following tables to the database:

JWKS

Table Name: jwks

Field NameTypeKeyDescription
id
string
Unique identifier for each web key
publicKey
string
-The public part of the web key
privateKey
string
-The private part of the web key
createdAt
Date
-Timestamp of when the web key was created

Options

Algorithm of the Key Pair

The algorithm used for the generation of the keypair. The default is EdDSA with the Ed25519 curve. Below are the available options:

auth.ts
jwt({
  jwks: {
    keyPairConfig: {
      alg: "EdDSA",
      crv: "Ed25519"
    }
  }
})

EdDSA

  • Default Curve: Ed25519
  • Optional Property: crv
    • Available options: Ed25519, Ed448
    • Default: Ed25519

ES256

  • No additional properties

RSA256

  • Optional Property: modulusLength
    • Expects a number
    • Default: 2048

PS256

  • Optional Property: modulusLength
    • Expects a number
    • Default: 2048

ECDH-ES

  • Optional Property: crv
    • Available options: P-256, P-384, P-521
    • Default: P-256

ES512

  • No additional properties

Disable private key encryption

By default, the private key is encrypted using AES256 GCM. You can disable this by setting the disablePrivateKeyEncryption option to true.

For security reasons, it's recommended to keep the private key encrypted.

auth.ts
jwt({
  disablePrivateKeyEncryption: true
})

Modify JWT payload

By default the entire user object is added to the JWT payload. You can modify the payload by providing a function to the definePayload option.

auth.ts
jwt({
  definePayload: (user) => {
    return {
      id: user.id,
      email: user.email,
      role: user.role
    }
  }
})

Modify Issuer, Audience or Expiration time

If none is given, the BASE_URL is used as the issuer and the audience is set to the BASE_URL. The expiration time is set to 15 minutes.

auth.ts
jwt({
  issuer: "https://example.com",
  audience: "https://example.com",
  expiresIn: "1h"
})

On this page

Edit on GitHub