CSRF protection for application API routes #1929
-
Is it appropriate to use NextAuth's getCsrfToken() for protecting application POST/PUT/PATCH/DELETE API routes that are unrelated to signIn/signOut, or are application developers encouraged to use their own anti-CSRF tokens? The following code seems to work fine, but I'm curious if there are any guidelines from NextAuth maintainers. page.js import {getCsrfToken} from 'next-auth/client';
export async function getServerSideProps(context) {
return {
props: {
csrfToken: await getCsrfToken(context),
},
}
}
export default function Page(props) {
// ...
fetch('/api/route',
{
method: 'POST',
body: JSON.stringify({
csrfToken: props.csrfToken,
// ...
}),
})
.then((res) => res.json())
.then((res) => {
// ...
});
// ...
} route.js import {getCsrfToken, getSession} from 'next-auth/client';
export default async (req, res) => {
const session = await getSession({req})
const csrfToken = await getCsrfToken({req});
if (!session) {
return res.status(401).json({error: 'You must be signed in to view the protected content on this page.'});
}
if (req.method === "GET") {
// Handle authenticated GET request
return res.send({content: 'This is protected content retrieved via GET. You can access this content because you are signed in.'})
} else if (req.method === "POST") {
const data = ((requestBody) => {
try {
return JSON.parse(requestBody);
} catch (err) {
return false;
}
})(req.body);
if ((data && data.csrfToken) !== csrfToken) {
return res.status(403).json({error: 'You must provide the correct csrfToken.'});
}
// Handle authenticated POST request
return res.send({content: 'Protected action was performed via POST. You can perform this action because you are signed in.'})
} else {
return res.status(405).json({error: 'The requested HTTP method is not supported.'});
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
I don't see a problem with that, but I wouldn't use a getServerSideProps just for that purpose. The CSRF token will be attached to each request so you could simply read it off of Although getCsrfToken does exactly that when you pass req to it, so you basically compare the cookie with itself. You can see the logic involved validating the csrfToken in the source code here: https://github.com/nextauthjs/next-auth/blob/main/src/server/lib/csrf-token-handler.js |
Beta Was this translation helpful? Give feedback.
I don't see a problem with that, but I wouldn't use a getServerSideProps just for that purpose. The CSRF token will be attached to each request so you could simply read it off of
req.cookies
I believe.Although getCsrfToken does exactly that when you pass req to it, so you basically compare the cookie with itself.
You can see the logic involved validating the csrfToken in the source code here:
https://github.com/nextauthjs/next-auth/blob/main/src/server/lib/csrf-token-handler.js