Share Auth Session Between NextJs Multi-Zones Apps Using NextAuth - Js - by Badjessa Roméo Bahoumda - Medium
Share Auth Session Between NextJs Multi-Zones Apps Using NextAuth - Js - by Badjessa Roméo Bahoumda - Medium
Save
One way of designing this system would be to split the project into two applications;
A customer facing app which takes care of the user experience and an internal
facing app which allows your employees to manage things such as vendors, products
etc…
NextJs Multi-zone allows you to split a big project into small pieces and even run
them separately while they appear as a unified application to your user base
(customers and internal employees).
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 1/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
Now that we resolved this issue, how do we share the authentication session of a
user (an admin for example) between the two applications given that they aren’t in
the same deployment container anymore? Let’s find out below!
Authentication Problem
NextAuth.js is a wonderful library that provides you with out of the box resources to
handle the authentication process in your NextJs app. While this works great for just
a single application, sharing a user session between apps gets a little gnarly and in
this article we aim to make this process a bit clearer.
Requirements
For this article I am making a couple of assumptions:
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 2/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
make
49 sureasync
to store the session
session({ cookie
session, token under
}) { the domain .ourdomain.com by
50 session.accessToken = token.accessToken;
extracting the domain from our NEXTAUTHURL in getDomainWithoutSubDomain . This
51 const { firstName, lastName, email, ... } = token.user;
way,
52 we make session.user
the cookie accessible
= { to all subdomains including our second
application.
53 name: `${firstName} ${lastName}`,
54 email: email,
We’ll
55 see how that...
works later
// Any (:
other data we want to store on the user
56 };
57 session.refreshToken = token.refreshToken;
This is a typical set up to allow NextAuth.js to authenticate our users. To log our
58 return session;
users
59
in, we
},
can simply call the signin method in our log in form. This will call our
custom
60 };backend and use our defined callbacks jwt and session to massage the data
61
into an appropriate format before storing it in a browser cookie.
62 const options = {
63 debug: false, // if you want to debug
164 importsecret:
{ signIn } from
//The 'next-auth/react';
secred that you use to hash your token
265 useSecureCookies,
366 // This call would
providers: [ be wrapped in your form component and bound to your login or submit
67 button CredentialsProvider({
468 const { email,name:
password } = values;
'credentials',
569 signIn('credentials', {
id: 'credentials',
670 email,async authorize(credentials, req) {
771 password, try {
872 callbackUrl: redirectUrl // the
const userData url to
= await redirect to on succesful login
axios.post(CUSTOM_AUTH_URL,
973 }); {
signin.js
74
hosted with ❤ by GitHub email: credentials.email, view raw
75 password: credentials.password
76 },
We77are done for the first application,
{ we should now be able to login in our initial
App.
78 You can get more information on how
headers: { all this works here https://next-
79 'accept': '*/*',
auth.js.org/getting-started/example
80 'Content-Type': 'application/json',
81 },
Sharing the authentication token
82 });
83
NextAuth.js
84 stores the authentication cookies
if (userData.status === inside
200) { of our browser. Below is an
example
85 of what it looks likereturn
for beta.udeesa.org
userData.data;
86 }
87 return null;
88
89 } catch (e) {
90 console.error(JSON.stringify(e));
91 // Redirecting to the login page with error messsage in the URL
92 throw new Error(e + '&email=' + credentials.email);
93 }
94 }
95 })
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 4/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
95 }),
After logging in, a couple of values are stored in our cookies. In our case, we care
96 ],
about
97 our session token ( …next.auth.session-token ) because it allows us to verify
callbacks,
that
98 our user has successfully been authenticated and we can fetch user data.
cookies,
99 pages: {
100
Setting up App//#2
set pages that tell nextauth where to redirect for an action
101 signIn: '/signin',
102 signOut: '/',
In our second app, we need to setup NextAuth but this time we do it a bit differently.
103 error: '/signin'
As104we did previously,
} we create a [...nextauth].js file to handle the authentication
process
105 };in this app.
106
107 const Auth = (req, res) => NextAuth(req, res, options);
108 export default Auth;
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 5/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
7
8 return urlParts
9 .slice(0)
10 .slice(-(urlParts.length === 4 ? 3 : 2))
11 .join('.');
12 };
13
14 const useSecureCookies = process.env.NEXTAUTH_URL.startsWith('https://');
15 const cookiePrefix = useSecureCookies ? '__Secure-' : '';
16 const hostName = getDomainWithoutSubdomain(process.env.NEXTAUTH_URL);
17
18 const cookies = {
19 sessionToken:
20 {
21 name: `${cookiePrefix}next-auth.session-token`,
22 options: {
23 httpOnly: true,
24 sameSite: 'lax',
25 path: '/',
26 secure: useSecureCookies,
27 domain: hostName == 'localhost' ? hostName : '.' + hostName // add a . in
front so that subdomains are included
28 },
29 },
30 };
31
32 const callbacks = {
33 async jwt({ token, user }) {
34 if (user) {
35 token.accessToken = user.access_token;
36 token.user = user.user;
37 token.refreshToken = user.refresh_token;
38 }
39
40 return token;
41 },
42
43 async session({ session, token }) {
44 session.accessToken = token.accessToken;
45 const { firstName, lastName, email, ... } = token.user;
46 session.user = {
47 name: `${firstName} ${lastName}`,
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 6/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
47 name: ${firstName} ${lastName} ,
You’ll
48 notice thatemail:
the authorize
email, function is empty here, the goal of this file is to
describe
49 how to grab
... the session. Authorizing our users should only be done by our
50 };
main application.
51 session.refreshToken = token.refreshToken;
52 return session;
Note:
53
The},secret used here should be
125 the same
1 as the one in the initial application.
54 };
Create
55 a HOC component to check that the user is authenticated
56 const options = {
Since
57 we want
debug:the pages in app #2 to be accessed when the user is authenticated. We
false,
can
58 create a Higher
secret: Order
// your Component and either wrap our entire app or the
secret,
59 useSecureCookies,
appropriate component around it. We can now check that our user is logged in or
60 cookies,
redirect
61 him to our [login page if need be.
providers:
62 CredentialsProvider({
63 name: 'credentials',
1 // This a wrapper that we will have around our protected pages
64 id: 'credentials',
2 // This will make sure that the user is logged in and if not, they will be redirected
65 // We don't do anything because the user should have already been
3 // to the login page
authenticated
4
66 // if thats not the case, you should redirect the user to app #1
5 import { useSession } from 'next-auth/react';
67 async authorize(credentials, req) { return null; }
6 import { NextRouter, useRouter } from 'next/router';
68 }),
7 import { SIGNIN_URL } from '../util/constants';
69 ],
8
70 callbacks,
9 export const ProtectedAdminRoute = ({ children }) => {
71 };
10 const router: NextRouter = useRouter();
72
11 const { status } = useSession({
73 const Auth = (req, res) => NextAuth(req, res, options);
12 required: true,
74 export default Auth;
13 onUnauthenticated: () => {
[
14 h] j h drouter.push(SIGNIN_URL),
i h ❤ b Gi H b // redirect to the log in page view raw
15 }
16 });
17 if (status === "loading") {
18 return <span>Loading...</span>
19 }
20
21 return children;
22 }
useSession will check the cookies for any session token in the domain example.com .
Our user already logged in app #1 so the session will exists and app #2 can then fetch
the user information and manipulate said data as it sees fit.
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 7/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
And that’s it, the session token can now be shared between both our application and
there is a single entry point for logging in.
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 8/9
02/01/2023, 15:12 Share Auth Session between NextJs Multi-zones apps using NextAuth.js | by Badjessa Roméo Bahoumda | Medium
https://medium.com/@romeobazil/share-auth-session-between-nextjs-multi-zones-apps-using-nextauth-js-5bab51bb7e31 9/9