The JSON Web Token (JWT) Authentication module provides a Drupal authentication provider that uses JWTs as the primary factor of authentication.

What is a JSON Web Token?

JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. JWTs can be signed using a secret (with HMAC algorithm) or a public/private key pair using RSA.

More information here: http://jwt.io/introduction/

Installation

For Drupal 9+, the preferred method is to install the module with composer:
composer require drupal/jwt:^1.0

JWT depends on the key module.

JWT ships with its own composer.json and depends on a 3rd party PHP library firebase/php-jwt. This dependency *may* change in the future.

Signing and/or validating JWTs requires a secret. The JWT module leverages the key module to manage these secrets. Once everything is installed, you will need to create a new key at Manage > Configuration > System > Keys (admin/config/system/keys). Add a new or existing key there. Pick the correct key type for the algorithm you want to use:

  • JWT HMAC Key
  • JWT RSA Key

JWT HMAC Key

For the issuing and validating your own JWTs, we recommend a file-based key of 512 bits, base64 encoded. You can generate this key with the following command:

head -c 64 /dev/urandom | base64 -w 0 > /path/to/private/dir/jwt.key.txt

JWT RSA Key

For the issuing and validating your own JWTs, we recommend a file-based key, using RSA with a minimum of 2048 bits. Going higher, up to 4096 bits, is worth considering. You can generate this key with the following command:

openssl genrsa 2048 > /path/to/private/dir/jwt.key.txt

If you need the public key (for validating but not generating JWT tokens issued with the above private key) you can extract it using:

openssl rsa -in /path/to/private/dir/jwt.key.txt -pubout

Once you have created a key, navigate to Configuration > System > JWT Authentication (admin/config/system/jwt). Choose the key that you just created in the previous step.

Issuing JWTs

Issuing JWTs means providing tokens which have been signed with a secret key. These JWTs may contain arbitrary information like user ids, specific privileges, or anything serializable into JSON.

Out-of-the-box, the JWT module does not immediately provide a means for accessing created JWTs. If you need an API which is able to provide JWTs, you will need to enable the JWT Authentication Issuer module.

Once enabled, the Issuer module creates an endpoint at /jwt/token which will generate JWTs for the logged in user that accesses it.

Note that an unofficial Drupal 7 port exists at https://github.com/cybtachyon/jwt

The API in the 8.x-1.x branch is stable and that branch is likely to get only minimal maintenance fixes. Assistance is sought to make a new 2.x branch to update for the changes in the 6.x+ version of the JWT library https://github.com/firebase/php-jwt

IMPORTANT: The 8.x-1.x branch's use of JWT is NOT vulnerable to CVE-2021-46743

See this advisory and related links: https://github.com/advisories/GHSA-8xf4-w7qw-pjjw

The vulnerability depends on using a keychain (multiple keys in an array or \ArrayAccess interface object) as the 2nd argument passed into JWT::decode(), and on having multiple algorithms passed in the array as the 3rd argument. In addition the keychain must have a mix of algorithm types such as both RS256 and HS256.

There are 3 modules in this project that have code that calls JWT::decode().

  1. The main jwt module calls it via \Drupal\jwt\Transcoder\JwtTranscoder. In JwtTranscoder the key is is a string (single value) not a keychain, and only one algorithm is passed as the 3rd argument. Thus it meets none of the conditions for the vulnerability.
  2. The jwt_path_auth module also calls it via JwtTranscoder, and thus it also meets none of the conditions for the vulnerability.
  3. The users_jwt module does use a keychain implemented by \Drupal\users_jwt\UsersJwtKeyRepository. The call to JWT::decode() in \Drupal\users_jwt\Authentication\Provider\UsersJwtAuth only passes a single algorithm ['RS256'] as the 3rd argument, so it does not meet the conditions for the vulnerability. In addition, this module is written such that each key does track the expected algorithm so a further check verifies that the key algorithm and the algorithm sent in the JWT match, preventing any possibility of algorithm confusion. Thus, it is not vulnerable.
Supporting organizations: 
Development and maintenance
Development and maintenance

Project information

Releases