How to Add a Custom OAuth2/OpenID Connect Provider to Strapi v4

Strapi - Mar 21 '23 - - Dev Community

In this article, we will cover the required steps to add a custom OAuth2/OpenID Connect provider to Strapi 4.

First things first, what are OAuth2 and OpenID Connect?
OAuth2 handles authorization whereas OpenID Connect handles authentication. What’s the difference you may ask, well, OAuth2 is built to manage authorization access to APIs with scopes, and OpenID Connect is built on top of OAuth2 to manage authentication of users.
Strapi actually relies on OpenID Connect protocol to retrieve user info and create the internal Strapi user upon provider account connection.
If you want more details on what are those and the differences, I can only recommend the OAuth2 and OpenID Connect: The Professional Guide ebook by the guys behind Auth0 by Okta.

Prerequisites

Before you can jump into this content, you need to have a basic understanding of the following.

  1. Basic knowledge of JavaScript
  2. A Node.js ready environment
  3. Basic understanding of Strapi - get started here ## What is Strapi

Strapi is an open-source headless CMS based on Node.js that is used to develop and manage content using a Restful API and/or GraphQL.

With Strapi, we can scaffold our API faster and consume the content via APIs using any HTTP client or GraphQL enabled frontend.

Scaffolding a Strapi project

To scaffold a new Strapi project is very simple and works precisely as installing a new frontend framework.

We are going to start by running the following commands and testing them out in our default browser.

    npx create-strapi-app strapi-api --quickstart
    # OR
    yarn create strapi-app strapi-api --quick start
Enter fullscreen mode Exit fullscreen mode

The command above will scaffold a new strapi project in the directory you specified.

Next, run yarn build to build your app and yarn develop to run the new project if it doesn't start automatically.

The last command will open a new tab with a page to register your new admin of the system. Go ahead and fill out the form and click on the submit button to create a new Admin.

Patch Package

What is it?

patch-package lets app authors instantly make and keep fixes to npm dependencies. It's a vital band-aid for those of us living on the bleeding edge.
Head over to its GitHub repo if you want to know more.

Why do we need it?

Well, Strapi manages OAuth2/OpenID Connect through a dependency, Grant. It then uses Purest to make some API calls to retrieve User information.
In order to have our OAuth2/OpenID Connect Provider to work with Strapi, we then have 2 options:

  1. Get those dependencies to add our Provider (good luck with that if it is not something mainstream) and then have Strapi to use them
  2. Patch those dependencies and add our own

I guess you figured we will go with the second option ;)

Set it up in your project

Simply follow its setup instructions

Grant

What is it?

Grant is an OAuth2/OpenID Connect proxy for Node.js with 200+ preconfigured providers.
More information in its GitHub repo

Which changes are needed?

First, we need to check if the provider you want to use already exists in grant in the oauth.json file

  1. It’s already there
    1. No patch required, you’re good to proceed to the next package
  2. It’s not listed
    1. That’s the case in which we need to patch it ## Prepare the changes
  3. Add the OAuth2/OpenId Connect provider to the node_modules/grant/config/oauth.json file
      "trackmania": {
        "authorize_url": "https://api.trackmania.com/oauth/authorize",
        "access_url": "https://api.trackmania.com/api/access_token",
        "oauth": 2,
        "scope_delimiter": " "
      }
Enter fullscreen mode Exit fullscreen mode
  • Add the OAuth2/OpenId Connect provider to the node_modules/grant/config/profile.json file
      "trackmania": {
        "profile_url": "https://api.trackmania.com/api/user"
      }
Enter fullscreen mode Exit fullscreen mode

Make it a patch

Execute the following command

    npm patch-package grant
    # OR
    yarn patch-package grant
Enter fullscreen mode Exit fullscreen mode

This will create the patches/grant+VERSION.patch file where VERSION is the one you have currently installed

Purest

What is it?

Purest is a REST API client library with embeded providers, think of it as an axios with preconfigured base urls and endpoints for each provider.
More information on its GitHub repo

Which changes are needed?

Same first step than Grant: Is your provider already listed in Purest?

  1. Yep!
    1. No patch required, you’re good to proceed to the next package
  2. Nope
    1. Let’s patch it! ## Prepare the changes
  3. Add the OAuth2/OpenID Connect provider to the node_modules/purest/config/providers.json file
      "trackmania": {
        "default": {
          "origin": "https://api.trackmania.com",
          "path": "api/{path}",
          "headers": {
            "authorization": "Bearer {auth}"
          }
        },
        "oauth": {
          "origin": "https://api.trackmania.com",
          "path": "oauth/{path}"
        }
Enter fullscreen mode Exit fullscreen mode

Make it a patch

Execute the following command

    npm patch-package purest
    # OR
    yarn patch-package purest
Enter fullscreen mode Exit fullscreen mode

This will create the patches/purest+VERSION.patch file where VERSION is the one you have currently installed

Strapi Plugin Users Permissions

What is it?

This is the Strapi’s internal way of handling Users and Permissions, in which the supported OAuth2/OpenID Connect providers are implemented

Which changes are needed?

We will need to edit multiple files for the provider to work, just follow along ;)

Prepare the changes

  • Add grant cofig in node_modules/@strapi/plugin-users-permissions/server/bootstrap/grant-config.js file
      trackmania: {
        enabled: true,
        icon: 'trackmania',
        key: '',
        secret: '',
        basicHeader: '',
        openPlanetSecret: '',
        callback: `${baseURL}/trackmania/callback`,
        scope:[]
      }
Enter fullscreen mode Exit fullscreen mode
  • Add implementation in node_modules/@strapi/plugin-users-permissions/server/services/providers-registry.js file
      async trackmania({ accessToken }) {
        const trackmania = purest({ provider: 'trackmania' });
        const { body: userBody } = await trackmania.get('user').auth(accessToken).request();

        // The userBody may differ from provider to provider, refer to the provider documentation for details
        return {
          username: userBody.displayName,
          email: userBody.email
        };
      }
Enter fullscreen mode Exit fullscreen mode

Make it a patch

Execute the following command

    npm patch-package @strapi/plugin-users-permissions
    # OR
    yarn patch-package @strapi/plugin-users-permissions
Enter fullscreen mode Exit fullscreen mode

This will create the patches/@strapi/plugin-users-permissions+VERSION.patch file where VERSION is the one you have currently installed

Conclusion

This article demonstrated how to add a custom Login Provider to Strapi 4.
Here is a demo repo where you’ll find an example implemetation.

Let me know if you have any question/suggestion, I’d love to hear your feedback ;)

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .