NextJS with full-stack authorization based on JWT and external API
Are you working on authorization for a Next.js based app?
Why is the authorization mechanism not so obvious for the Next.js app?
What should you focus on?
In this article I’ll try to answer the questions above and show a solution based on NextAuth library and Drupal.
You can use the following example as a high-level model of the application architecture.
Before you — start make sure you understand JWT technology.
About Next.js
Next.js is a framework based on React and Node.js that is dedicated for creating faster and easier universal web apps.
When working with Next.js, as a frontend developer, you should focus on both parts of the application — a client (browser) and a server side.
Keep in mind that Next.js is not dedicated for creating full-stack web applications with advanced data and a business layer model.
Nevertheless Next.js works both on the browser, and on the server, but still focuses on the presentation layer.
Creating universal web apps in Nextjs gives many benefits such as better seo or application speed but it does make some things more complicated.
Check out my previous article about creating an authorization from scratch and see how Universal Apps work and share data between browser and serwer.
Why Nextauth?
Nextauth is a library created by a community for other developers to help quickly solve the hardest parts of universal applications.
Main features:
- build-in many providers
- API for creating own provider
- full-stack solution (supports SSR and CSR)
- build-in auto-refresh session
- security (signed cookies, csrf token)
- authorization based on JWT or database session
- browser tabs sync
Solution
In this example we’ll use a custom provider for authorization and make API calls.
We will use Drupal as our authorization provider and data source, but you can use this pattern with any API supporting token-based authentication.
NextAuth extends our Next.js app with several endpoints which can be used for managing and checking our authorization state.
See step-by-step tutorial in the documentation (https://next-auth.js.org/getting-started/introduction )
Login flow
Let’s take a look at the diagram below and see how the login process works.
- We start from the call to api/auth/callback/credentials
- on the Nextjs’s server-side, we pass the request to the external (Drupal) api to check our credentials
- if the credentials are correct, the Drupal API will respond with a json-web-token (JWT) including the
access_token
and basic user data - we then receive response from Drupal API, and create another JWT (let’s call it “JWT Nextjs”) where we store the
access_token
from Drupal and some user’s data - finally we send a response to the browser, including a signed cookie with the “JWT Nextjs” token
- now each session is validated in Next.js
API request flow
Now we’ll try to get some data from Drupal API. We’ll use the custom Next.js endpoints as a proxy, and add “on-the-fly” some necessary data (user id, access_token).
- first we make a request to the custom endpoint
api/whatever/:my_params
- then we extract (from “JWT Next”) the necessary data (the most important is
access_token
) and addaccess_token
to the request header - finally we call to Drupal API
- and send received data to the browser
- if Drupal API responds with 403 status we should invalidate our “JWT Nextjs” token and re-authorize the user.
Code
Login configuration
Provider configuration (we use a custom provider https://next-auth.js.org/providers/credentials )
Api call configuration
See how to protect server-side route, get an access_token
from `JWT Next` and make a request to an external API.
Summary
Creating solution which cover all cases in Next.js is hard and takes some time. Nextauth.js gives us out-of-the-box control over user’s session on the client and server side. Check how to use it with other authentications providers (e.g. OAuth, OIDC, and others..).