Pre-requisites
- Cloned the nextAuth example repo and installed dependencies (You can also see the end result after adding Dynamic here).
Steps
Add the right env variables
You’ll need to define two environment variables in your.env.local
file:
.env.local
file, and you’re good to go.
Add the Dynamic Provider
We are going to use the Dynamic UI on the client, so the first thing we’ll want to do is add an initialize the DynamicContextProvider and then we can use the DynamicWidget UI. First make sure you have the appropriate dependencies installed:layout.tsx
file:
Add the DynamicWidget
You don’t need to add the widget at the same level as the provider, you can place this anywhere. For this example we’ll add it to the header:events
which Dynamic provides but let’s come back to that and first add the server side code.
Define the JWT decoding
NextAuth needs to know how to decode and validate the JWT which Dynamic sends back. To do this we’ll create a custom JWT decoder inside a new helper file:getKey
function which is used to fetch the public key which you can use to decode the JWT. This function will make an API call to Dynamic. We’ll add this to the same file:
Update the NextAuth configuration
You can copy the below code and paste it over the full existing auth.ts file in the demo repo:Trigger the JWT validation on login
We’ll need to access the JWT which Dynamic sends back after a user has logged in so that we can co-ordinate with NextAuth. To do this we’ll use one of the events which Dynamic provides. Back in thedynamic-wrapper.ts
file we’ll adjust the settings object passed to DynamicContextProvider as a prop to the following:
getCsrfToken
function which NextAuth provides. This is important because NextAuth uses CSRF tokens to prevent CSRF attacks.
Token Scopes
A JWT token supports the concept of scopes, which are used to define the permissions that the token has. Dynamic uses various scopes to identify limitations for a token. The most common and important scope value isrequiresAdditionalAuth
which signifies that the token requires MFA to be completed before the token is considered valid and the user is fully authenticated.
Our SDK handles this for the frontend, but for the backend you will need to check this scope and handle it accordingly.
To do this, you can add a check for the requiresAdditionalAuth
scope in the authorize
function in the auth.ts
file:
null
if you do not want to handle the token with the requiresAdditionalAuth
scope.
Run the example
Going further
You’ll see in auth.js that we are assigning certain JWT fields to a user object. You can add any fields you want to this object, and then access them in your pages via theuseSession
hook.