0%

NextJs Work With Microservice (Auth Server)

problem description

nextjs get token from another site(usually oauth server) and send the token to the next js server(the server which host the nextjs generate the web page and send to your browser) to let it use in getserverprops, then we can protect our route or fetch some auth-need data before render

solution

You can use an HTTP-only cookie to store the token and pass it between the client and server. This approach works with serverless deployments and multiple instances.

Here's a solution using TypeScript and the next-iron-session package to store the token in an encrypted cookie:

  1. Install the required dependencies:
1
npm install next-iron-session cookie
  1. Configure next-iron-session: Create a file iron-session-config.ts in the root folder of your project (my_project/src/iron-session-config.ts): notice: the sessionOption password field need to at least 32 words
1
2
3
4
5
6
7
8
9
10
11
import { SessionOptions } from 'next-iron-session';

const sessionOptions: SessionOptions = {
cookieName: 'nextjs_token_cookie',
password: process.env.SECRET_COOKIE_PASSWORD || 'default_password_please_change_fuck_you_at_least_32_word',
cookieOptions: {
secure: process.env.NODE_ENV === 'production',
},
};

export default sessionOptions;
  1. Update your API route to store the token in the session: Update the pages/api/token.ts file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { NextApiRequest, NextApiResponse } from 'next';
import { withIronSession } from 'next-iron-session';
import sessionOptions from '../../iron-session-config';

const handler = async (req: NextApiRequest, res: NextApiResponse) => {
if (req.method === 'POST') {
const token = req.body.token;

// Store the token in the session
req.session.set('token', token);
await req.session.save();

res.status(200).json({ message: 'Token stored successfully' });
} else {
res.status(405).json({ message: 'Method not allowed' });
}
};

export default withIronSession(handler, sessionOptions);
  1. Update getServerSideProps to retrieve the token from the session:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { GetServerSideProps } from 'next';
import { withIronSession } from 'next-iron-session';
import sessionOptions from '../iron-session-config';

export const getServerSideProps: GetServerSideProps = withIronSession(
async ({ req, res }) => {
// Retrieve the token from the session
const token = req.session.get('token');

// Use the token to fetch data or perform other actions on the server-side

return {
props: {
// Pass any data you fetched to your component as props
},
};
},
sessionOptions,
);

  1. Then you can send your auth token to save it in the web server after you login
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
async function sendTokenToServer(token: string): Promise<void> {
const response = await fetch('/api/token', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ token }),
credentials: 'include', // Include session cookie
});

if (response.ok) {
console.log('Token stored successfully');
} else {
console.error('Failed to store token');
}
}

export default function Login() {
const handleSubmit = async (e: React.SyntheticEvent<HTMLFormElement>) => {
e.preventDefault();
const response = await login(email, password);
token = getTokenFromResponse(response)

// ... the rest of the code remains the same

await sendTokenToServer(token);

// ... the rest of the code remains the same
};
}