JWT validation

In this guide we will see how to validate a JWT (JSON Web Token) with a third party service.

When you sign in with the authentication route POST /auth/local, Strapi generates a JWT which lets your users request your API as an authenticated one.

  1. {
  2. "jwt": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MSwiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNTcxODIyMDAzLCJleHAiOjE1NzQ0MTQwMDN9.T5XQGSDZ6TjgM5NYaVDbYJt84qHZTrtBqWu1Q3ShINw",
  3. "user": {
  4. "email": "admin@strapi.io",
  5. "id": 1,
  6. "username": "admin"
  7. }
  8. }

These users are managed in the application’s database and can be managed via the admin dashboard.

We can now imagine you have a JWT that comes from Auth0JWT validation - 图1 (opens new window) and you want to make sure the JWT is correct before allowing the user to use the Strapi API endpoints.

Customize the JWT validation function

We will update the function that validates the JWT. This feature is powered by the Users & Permissions plugin.

Here is the file we will have to customize: permission.jsJWT validation - 图2 (opens new window)

  • We have to create a file that follows this path ./extensions/users-permissions/config/policies/permissions.js.
  • You will have to add in this new file, the same content of the original one.

Now we are ready to create our custom validation code.

Write our own logic

First we have to define where we write our code.

  1. const _ = require('lodash');
  2. module.exports = async (ctx, next) => {
  3. let role;
  4. if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
  5. try {
  6. const { id, isAdmin = false } = await strapi.plugins[
  7. 'users-permissions'
  8. ].services.jwt.getToken(ctx);
  9. ...
  10. } catch (err) {
  11. // It will be there!
  12. return handleErrors(ctx, err, 'unauthorized');
  13. }

The jwt.getToken will throw an error if the token doesn’t come from Strapi. So if it’s not a Strapi JWT token, let’s test if it’s an Auth0 one.

We will have to write our validation code before throwing an error.

By using the Auth0 get user profileJWT validation - 图3 (opens new window) documentation, you will verify a valid user matches with the current JWT

  1. const _ = require('lodash');
  2. const axios = require('axios');
  3. module.exports = async (ctx, next) => {
  4. let role;
  5. if (ctx.request && ctx.request.header && ctx.request.header.authorization) {
  6. try {
  7. const { id, isAdmin = false } = await strapi.plugins[
  8. 'users-permissions'
  9. ].services.jwt.getToken(ctx);
  10. ...
  11. } catch (err) {
  12. try {
  13. const data = await axios({
  14. method: 'post',
  15. url: 'http://YOUR_DOMAIN/userinfo',
  16. headers: {
  17. Authorization: ctx.request.header.authorization
  18. }
  19. });
  20. // if you want do more validation test
  21. // feel free to add your code here.
  22. return await next();
  23. } catch (error) {
  24. return handleErrors(ctx, new Error('Invalid token: Token did not match with Strapi and Auth0'), 'unauthorized');
  25. }
  26. }

WARNING

In the code example we use axios, so you will have to install the dependency to make it work. You can choose another library if you prefer.