Reputation: 1265
I'm trying to delete a cookie using the next/headers module in a Next.js application, but it doesn't seem to work as expected. Here's the code snippet:
import {cookies} from "next/headers";
export default async function Signout() {
async function deleteTokens() {
"use server"
cookies().delete('accessToken')
}
await deleteTokens()
return (
<></>
);
}
I expected the cookies().delete('accessToken') line to delete the cookie named "accessToken", but it doesn't seem to have any effect. The cookie is still present after the function is executed.
I am getting following error: Error: Cookies can only be modified in a Server Action or Route Handler. Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#cookiessetname-value-options
But i have set the "use server" and enabled it in the next.config.js
#using Next.js 13.4.4
Upvotes: 12
Views: 13896
Reputation: 29
To address the issue of being unable to delete a cookie using Next.js server-side action, you can utilize the following approach:
'use server';
import { cookies } from 'next/headers';
/**
* Function to remove JWT cookies.
* @returns {Promise<void>} A Promise that resolves once cookies are deleted.
*/
export async function removeJWTCookies() {
// Retrieve all cookies
const allCookies = cookies().getAll();
// Iterate through each cookie
allCookies.forEach((cookie) => {
// Delete the cookie
cookies().delete(cookie.name);
});
}
This solution utilizes the next/headers module to handle cookies. The removeJWTCookies function retrieves all cookies using cookies().getAll(), iterates through them, and deletes each cookie individually. This approach ensures that JWT cookies are properly removed from the server-side context.
Upvotes: -1
Reputation: 1
This works for me, I use a cookie httpOnly: true, sameSite: 'lax' and domain: '.exampledomain.com' to allow my subdomains to access the cookie.
Cookie definition:
res.cookie('token', token, {
maxAge: 60 * 60 * 1000, // 1hour (in milliseconds)
httpOnly: true,
secure: true, // Set to true if using HTTPS
sameSite: 'lax',
domain: '.exampledomain.com'
});
To delete the cookie in Nextjs server action:
'use server';
import { cookies } from 'next/headers'
import { redirect } from 'next/navigation';
const logout = async () => {
cookies().delete({ name: 'token', domain: '.exampledomain.com', path:'/' });
redirect('/login');
}
export default logout;`
check in the inspector the name, domain, path
Upvotes: 0
Reputation: 3428
The issue here is that your function runs as part of the server component, not as a server action. You can execute your function as a server action by passing it down to a client component and calling it from a client component on page load.
// app/signout/page.js
import { cookies } from "next/headers";
import SignOutAction from "./SignOutAction";
export default async function SignOut() {
async function deleteTokens() {
"use server";
cookies().delete("accessToken");
}
return <SignOutAction deleteTokens={deleteTokens} />;
}
// app/signout/SignOutAction.js
"use client";
import { useEffect, useRef } from "react";
export default function SignOutAction({ deleteTokens }) {
const deleteTokensRef = useRef(deleteTokens);
useEffect(() => {
deleteTokensRef.current = deleteTokens;
});
useEffect(() => {
deleteTokensRef.current();
}, []);
return null;
}
P.S. This is not directly related to your original question, but this implementation is prone to CSRF vulnerability - https://security.stackexchange.com/questions/62769/should-login-and-logout-action-have-csrf-protection
Upvotes: 3
Reputation: 49571
maybe you need to use set
method on actions. from here
Good to know: .set() is only available in a Server Action or Route Handler
To "delete" a cookie, you must set a new cookie with the same name and an empty value. You can also set the maxAge to 0 to expire the cookie immediately.
example from same docs:
'use server'
import { cookies } from 'next/headers'
async function create(data) {
cookies().set({
name: 'name',
value: '',
expires: new Date('2016-10-05'),
path: '/', // For all paths
})
}
from this issue, it might after 13.4.2
Upvotes: 0