Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Next.js authentication with existing backend
Szymon Kabelis
Szymon Kabelis

Posted on

     

Next.js authentication with existing backend

Recently I was working on some Next.js project and came to issues regarding the authentication using a built-in Next.js server and theexisting backend that holds whole logic and access to a database.

I had a problem with understanding how the next-auth is working and how to properly use thecredentials provider, or even if it can be used with an existing backend.

So, shortly, the answer isyes! You can use the credentials provider and make auth working together with an existing backend.

In this post, I will just focus on making auth working between the Next.js server and the existing API. If you need to set up the auth in the Next.js app from scratch, please follow the docs mentioned below.

Basics

Before I proceed to Next.js and auth itself I just want to mention that it would be good if you understand the basics correctly. I've prepared the list of links with useful content:

Next.js:

JWT:

Credentials provider

Next-auth lib gives various providers to authenticate against but we are interested in the classic one, just with the username and email. In fact, it doesn't care if you are using an existing backend or do all the auth stuff in the Next.js server (but in that case you should think about a different provider).

So, as the docs stand, the first thing you need to do is a setup of provider:

providers:[Providers.Credentials({name:'Credentials',credentials:{username:{label:"Username",type:"text",placeholder:"jsmith"},password:{label:"Password",type:"password"}},asyncauthorize(credentials){// Here call your API with data passed in the login formconsttoken=awaitloginEndpoint(credentials);if(token){returntoken}else{returnnull}}})]
Enter fullscreen modeExit fullscreen mode

Inauthorize() handler you need to make a request to your API to auth the user and if credentials are correct you can return the response (or directly the token).

And now you need to set up thejwt() callback. It can look like that:

constcallbacks={asyncjwt(prevToken,token){// Initial callif(token){return{accessToken:token,};}// Subsequent callsreturnprevToken;}};
Enter fullscreen modeExit fullscreen mode

This should work fine. But there is one issue.

Expired token issue

The token you get from your API is not refreshed. So, you can have a situation when auth between theNext.js client andNext.js server works fine but the token you have from your API hasexpired.

So, to make requests from the client through the Next.js server to your API, you would need to logout and login once again to have a valid token.

Solution

You can't just set the options ofsession.maxAge to match the one from the API you are using because every time you access the site (assuming you are using next-auth) time of the session is automatically extended.

However, what you can do is,manually set the expired time by hardcoding a value or returning the expired time value from the login/refresh endpoint. See how the code looks in that case:

constrefreshAccessToken=async(prevToken)=>{consttoken=awaitrefreshEndpoint(prevToken);// Do what you wantreturn{accessToken:token.accessToken,accessTokenExpires:Date.now()+token.expiresIn*1000,};}constcallbacks={asyncjwt(prevToken,token){// Initial callif(token){return{accessToken:token.accessToken,// Assuming you can get the expired time from the API you are using// If not you can set this value manuallyaccessTokenExpires:Date.now()+token.expiresIn*1000,};}// Subsequent calls// Check if the expired time set has passedif(Date.now()<prevToken.accessTokenExpires){// Return previous token if still validreturnprevToken;}// Refresh the token in case time has passedreturnrefreshAccessToken(prevToken);},}
Enter fullscreen modeExit fullscreen mode

As you can see, in the initial call, you need to set the expired time based on what the API returns or just hardcode the value (e.g.30 * 30 - 1 hour).

Then, whenever the session is checkedjwt() callback is called and the current time is compared to expired. If it's passed then you need to call therefreshAccessToken function, in which you can refresh the token using the API, otherwise, the previous token is returned because it still can be used.

With this approach, you can usethe Next.js server as a proxy between the client app and the API you are using. This can be very useful due to the power of Next.js API Routes.

If you have any questions, let me know in the comments.

Top comments(11)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
dededavida profile image
David Cruz
  • Joined

Hi guys, if you need the token in an axios request, do it like this!

api.tsx

CollapseExpand
 
wparad profile image
Warren Parad
Long time software architect, CTO Authress, creating application security plug-ins for any software application with Authress. Talk to me about security in microservices or service authorization.
  • Location
    Switzerland
  • Work
    CTO @Authress
  • Joined

Will have to say, it's much easier to pull in a package such asfederated auth to do this automatically. You don't need to set anything extra or understand how JWTs are supported to work to make sure the UI app works correctly.

CollapseExpand
 
szymkab profile image
Szymon Kabelis
Software developer with 5+ years of experience. Currently focused on web apps and web games. Check my site https://frontendgamedev.com/ where you can find useful information about web games.
  • Location
    Poland
  • Joined

Well, I would say using next-auth doesn't require knowing JWTs but I've included that in the post because I think it's always better to know at least something about what you are using...

CollapseExpand
 
wparad profile image
Warren Parad
Long time software architect, CTO Authress, creating application security plug-ins for any software application with Authress. Talk to me about security in microservices or service authorization.
  • Location
    Switzerland
  • Work
    CTO @Authress
  • Joined

Sure, but it's better than to put that as the perspective in the article. "Hey, this is difficult, there are packages to handle it, and here we are going to dive into why these packages exist and what they are providing."

Thread Thread
 
jaketone profile image
Jake
  • Joined

Quite an aggressive way of referring others to your own package. Thank you@szymkab for the simple concept.

CollapseExpand
 
dwalker93 profile image
Adam Walker
  • Joined

Hey Szymon this is great article.. But using this how to send authenticated requests to another server?
For example next app in client and main express graphql api in another api path. how to send authenticated request to other server?

CollapseExpand
 
szymkab profile image
Szymon Kabelis
Software developer with 5+ years of experience. Currently focused on web apps and web games. Check my site https://frontendgamedev.com/ where you can find useful information about web games.
  • Location
    Poland
  • Joined

Hi, do you want to send requests from Next.js client (browser react app) or server?

CollapseExpand
 
dwalker93 profile image
Adam Walker
  • Joined

yeah for example my front next js app in client folder and backend express graphql server in server folder. I can set token as a header when request from next to graphql api. but how to decode that jwt in graphql api ?

CollapseExpand
 
msahil1 profile image
msahil1
  • Joined

Hi
great info, Could also tell how we can do NextAuth Google login with exisitng backend API as backend API releases its own token.

CollapseExpand
 
Sloan, the sloth mascot
Comment deleted
CollapseExpand
 
dmtrbch profile image
Dimitar Bochvarovski
  • Joined

Hello, is it possible to use this method for authentication with existing backend, but with other providers, such as google, twitter...

Thanks in advance

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Software developer with 5+ years of experience. Currently focused on web apps and web games. Check my site https://frontendgamedev.com/ where you can find useful information about web games.
  • Location
    Poland
  • Joined

Trending onDEV CommunityHot

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp