Cookies
Unanswered
Mini Lop posted this in #help-forum
Mini LopOP
I cant delete cookies after setting up, I've tried all from the documentation but still not deleting it. Please help me
62 Replies
@Mini Lop I cant delete cookies after setting up, I've tried all from the documentation but still not deleting it. Please help me
try
cookies().set("cookieName", "", { maxAge: -1 });Mini LopOP
OK thank you, im trying
Mini LopOP
It didnt work
I got error, cookies can only be modified in sever action or route handler... but I've marked the top "use server"
how do you use it? can you show some code?
Mini LopOP
ok here is how i use it .
"use server"
import { cookies } from "next/headers";
import jwt, { TokenExpiredError } from "jsonwebtoken";
interface RequestCookie {
id: string;
// Add other properties as needed
}
const TOKEN_COOKIE_NAME = "token";
export async function checkTokenExpiration() {
const cookiesStore = cookies();
const tokenValue = cookiesStore.get(TOKEN_COOKIE_NAME);
try {
if (!tokenValue || !tokenValue.value) {
console.log("Token is missing or invalid");
return;
}
const decode: RequestCookie | undefined = await jwt.verify(tokenValue.value, process.env.TOKEN_SECRET!);
// Check if the token has expired
if (!decode) {
console.log("Token is invalid or expired. Deleting the token cookie.");
cookiesStore.set(TOKEN_COOKIE_NAME, '',
{ maxAge: -1 }
);
return;
}
console.log("Token is still valid");
} catch (error) {
if (error instanceof TokenExpiredError) {
cookiesStore.set(TOKEN_COOKIE_NAME, '',
{ maxAge: -1 }
);
console.log("Token has expired. Deleting the token cookie.");
return;
}
console.error("Error decoding token", error);
}
}
// Run the check every 10 minutes (600,000 milliseconds)
// setInterval(checkTokenExpiration, 600000);
import { cookies } from "next/headers";
import jwt, { TokenExpiredError } from "jsonwebtoken";
interface RequestCookie {
id: string;
// Add other properties as needed
}
const TOKEN_COOKIE_NAME = "token";
export async function checkTokenExpiration() {
const cookiesStore = cookies();
const tokenValue = cookiesStore.get(TOKEN_COOKIE_NAME);
try {
if (!tokenValue || !tokenValue.value) {
console.log("Token is missing or invalid");
return;
}
const decode: RequestCookie | undefined = await jwt.verify(tokenValue.value, process.env.TOKEN_SECRET!);
// Check if the token has expired
if (!decode) {
console.log("Token is invalid or expired. Deleting the token cookie.");
cookiesStore.set(TOKEN_COOKIE_NAME, '',
{ maxAge: -1 }
);
return;
}
console.log("Token is still valid");
} catch (error) {
if (error instanceof TokenExpiredError) {
cookiesStore.set(TOKEN_COOKIE_NAME, '',
{ maxAge: -1 }
);
console.log("Token has expired. Deleting the token cookie.");
return;
}
console.error("Error decoding token", error);
}
}
// Run the check every 10 minutes (600,000 milliseconds)
// setInterval(checkTokenExpiration, 600000);
i also try it in my middleware but it seems its not working too import { NextRequest, NextResponse } from "next/server"
export default async function middleware(req:NextRequest) {
const { pathname } = req.nextUrl
const isPublicPath = pathname === "/" "/sign-in";
const token = req.cookies.get('token')?.value '';
if(!isPublicPath && token){
return NextResponse.redirect(new URL('/',req.nextUrl))
}
if(!isPublicPath && !token){
return NextResponse.redirect(new URL('/sign-in',req.nextUrl))
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
/
'/((?!api|_next/static|_next/image|favicon.ico).)',
],
}
export default async function middleware(req:NextRequest) {
const { pathname } = req.nextUrl
const isPublicPath = pathname === "/" "/sign-in";
const token = req.cookies.get('token')?.value '';
if(!isPublicPath && token){
return NextResponse.redirect(new URL('/',req.nextUrl))
}
if(!isPublicPath && !token){
return NextResponse.redirect(new URL('/sign-in',req.nextUrl))
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
/
'/((?!api|_next/static|_next/image|favicon.ico).)',
],
}
Mini LopOP
But what about the other function
@Mini Lop But what about the other function
its fine to use
cookies() in server actionMini LopOP
But its give the error I sent you earlier
where do you use the action?
are you executing it in a page component directly?
Mini LopOP
Yes
Mini LopOP
import { cookies } from "next/headers";
import { fetchAdmin } from "../actions/admin.actions";
import jwt, { TokenExpiredError } from "jsonwebtoken"
import { checkTokenExpiration } from "./delete-token";
interface RequestCookie {
id: string;
username: string;
firstname: string;
middlename: string;
lastname: string;
phone: string;
email: string;
dob: string;
role: string;
gender: string;
maritalstatus: string;
currentaddress: string;
permanentaddress: string;
iat: Date
exp: Date
}
interface UserProfileResponse {
success: boolean;
message: string;
user?: any; // Add the actual user type/interface
}
export async function currentProfile() {
const cookiesStore = cookies();
const tokenValue = cookiesStore.get("token");
try {
await checkTokenExpiration()
if (!tokenValue || !tokenValue.value) {
return null;
}
const decode: RequestCookie | undefined = await jwt.verify(tokenValue.value, process.env.TOKEN_SECRET!);
console.log(decode)
// Check if the token has expired
if (!decode) {
return null;
}
const user = await fetchAdmin({ id: decode?.id });
if (!user) {
return null;
}
return user
} catch (error) {
if (error instanceof TokenExpiredError) {
return;
}
console.error("Error decoding token", error);
return;
}
}
import { fetchAdmin } from "../actions/admin.actions";
import jwt, { TokenExpiredError } from "jsonwebtoken"
import { checkTokenExpiration } from "./delete-token";
interface RequestCookie {
id: string;
username: string;
firstname: string;
middlename: string;
lastname: string;
phone: string;
email: string;
dob: string;
role: string;
gender: string;
maritalstatus: string;
currentaddress: string;
permanentaddress: string;
iat: Date
exp: Date
}
interface UserProfileResponse {
success: boolean;
message: string;
user?: any; // Add the actual user type/interface
}
export async function currentProfile() {
const cookiesStore = cookies();
const tokenValue = cookiesStore.get("token");
try {
await checkTokenExpiration()
if (!tokenValue || !tokenValue.value) {
return null;
}
const decode: RequestCookie | undefined = await jwt.verify(tokenValue.value, process.env.TOKEN_SECRET!);
console.log(decode)
// Check if the token has expired
if (!decode) {
return null;
}
const user = await fetchAdmin({ id: decode?.id });
if (!user) {
return null;
}
return user
} catch (error) {
if (error instanceof TokenExpiredError) {
return;
}
console.error("Error decoding token", error);
return;
}
}
i would do it in middleware instead
Mini LopOP
Oh ok
Thank you, but please how I did the middleware to check authentication, is it right?
@Mini Lop Thank you, but please how I did the middleware to check authentication, is it right?
something like this
export async function middleware(req: NextRequest) {
const tokenValue = req.cookies.get("token");
try {
if (!tokenValue || !tokenValue.value) {
return NextResponse.redirect("/login");
}
const decode: RequestCookie | undefined = await jwt.verify(
tokenValue.value,
process.env.TOKEN_SECRET!
);
// Check if the token has expired
if (!decode) {
return NextResponse.redirect("/login");
}
const user = await fetchAdmin({ id: decode?.id });
if (!user) {
return NextResponse.redirect("/login");
}
} catch (error) {
req.cookies.delete("token");
return NextResponse.redirect("/login");
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
*/
"/((?!api|_next/static|_next/image|favicon.ico).*)",
],
};Mini LopOP
OK thank you, im trying
Mini LopOP
now im getting new error
⨯ ./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
| <head>
Import trace for requested module:
./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
./node_modules/@mapbox/node-pre-gyp/lib/ sync ^./.*$
./node_modules/@mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/bcrypt/bcrypt.js
./lib/actions/admin.actions.ts
Module parse failed: Unexpected token (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
<!doctype html>| <html>
| <head>
Import trace for requested module:
./node_modules/@mapbox/node-pre-gyp/lib/util/nw-pre-gyp/index.html
./node_modules/@mapbox/node-pre-gyp/lib/ sync ^./.*$
./node_modules/@mapbox/node-pre-gyp/lib/node-pre-gyp.js
./node_modules/bcrypt/bcrypt.js
./lib/actions/admin.actions.ts
ah
you use bcrypt in fetchAdmin?
Mini LopOP
No
export async function fetchAdmin({id}:FetchAdminProps){
await connectToDB();
try {
const user = await Adminuser.findById({_id:id});
if(!user){
console.log("user doesnt exist")
return null
}
// Exclude sensitive information like password
const { password, ...userWithoutPassword } = user.toObject();
return userWithoutPassword;
} catch (error:any) {
console.log("Unable to fetch user",error)
}
}
await connectToDB();
try {
const user = await Adminuser.findById({_id:id});
if(!user){
console.log("user doesnt exist")
return null
}
// Exclude sensitive information like password
const { password, ...userWithoutPassword } = user.toObject();
return userWithoutPassword;
} catch (error:any) {
console.log("Unable to fetch user",error)
}
}
here is the function
do you use bcrypt?
Adminuser is mongoose?
Mini LopOP
yes mongoose
and you using bcrypt inside mongoose right?
Mini LopOP
not in that function, i use it in different function when login user
i use bcrypt here "use server"
import { compare } from "bcrypt";
import Adminuser from "../models/admin.models";
import { connectToDB } from "../mongoose"
import { cookies } from "next/headers";
import jwt from "jsonwebtoken";
interface loginAdminUsersProps {
userName: string;
password: string;
}
export async function loginAdminUsers({ userName, password }: loginAdminUsersProps) {
await connectToDB();
const cookieStore = cookies();
try {
const user = await Adminuser.findOne({ userName })
if (!user) {
console.log("User doesnt exist")
return null
};
const tokenData = {
id: user?._id,
username: user?.userName,
firstname: user?.firstName,
middlename: user?.middleName,
lastname: user?.lastName,
phone: user?.phone,
email: user?.email,
dob: user?.dob,
role: user?.role,
gender:user?.gender,
maritalstatus:user?.maritalStatus,
currentaddress:user?.currentAddress,
permanentaddress:user?.permanentAddress,
};
const isPasswordValid = await compare(password, user.password);
if (!isPasswordValid) {
console.log("password is invalid");
return
} else {
console.log("user is login")
}
const token = await jwt.sign(tokenData, process.env.TOKEN_SECRET!, { expiresIn: '2h' });
cookieStore.set("token", token,
{ httpOnly: true }
);
return user;
} catch (error: any) {
console.log("Unable to login admin", error);
}
}
import { compare } from "bcrypt";
import Adminuser from "../models/admin.models";
import { connectToDB } from "../mongoose"
import { cookies } from "next/headers";
import jwt from "jsonwebtoken";
interface loginAdminUsersProps {
userName: string;
password: string;
}
export async function loginAdminUsers({ userName, password }: loginAdminUsersProps) {
await connectToDB();
const cookieStore = cookies();
try {
const user = await Adminuser.findOne({ userName })
if (!user) {
console.log("User doesnt exist")
return null
};
const tokenData = {
id: user?._id,
username: user?.userName,
firstname: user?.firstName,
middlename: user?.middleName,
lastname: user?.lastName,
phone: user?.phone,
email: user?.email,
dob: user?.dob,
role: user?.role,
gender:user?.gender,
maritalstatus:user?.maritalStatus,
currentaddress:user?.currentAddress,
permanentaddress:user?.permanentAddress,
};
const isPasswordValid = await compare(password, user.password);
if (!isPasswordValid) {
console.log("password is invalid");
return
} else {
console.log("user is login")
}
const token = await jwt.sign(tokenData, process.env.TOKEN_SECRET!, { expiresIn: '2h' });
cookieStore.set("token", token,
{ httpOnly: true }
);
return user;
} catch (error: any) {
console.log("Unable to login admin", error);
}
}
hmm..can you show the code in middleware.ts?
Mini LopOP
import { NextRequest, NextResponse } from "next/server"
import jwt from "jsonwebtoken"
import { fetchAdmin } from "./lib/actions/admin.actions";
export async function middleware(req: NextRequest) {
const tokenValue = req.cookies.get("token");
try {
if (!tokenValue || !tokenValue.value) {
return NextResponse.redirect("/sign-in");
}
const decode = await jwt.verify(
tokenValue.value,
process.env.TOKEN_SECRET!
);
// Check if the token has expired
if (!decode) {
return NextResponse.redirect("/sign-in");
}
const user = await fetchAdmin({ id: decode?.id });
if (!user) {
return NextResponse.redirect("/sign-in");
}
} catch (error) {
req.cookies.delete("token");
return NextResponse.redirect("/sign-in");
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
/
"/((?!api|_next/static|_next/image|favicon.ico).)",
],
};
import jwt from "jsonwebtoken"
import { fetchAdmin } from "./lib/actions/admin.actions";
export async function middleware(req: NextRequest) {
const tokenValue = req.cookies.get("token");
try {
if (!tokenValue || !tokenValue.value) {
return NextResponse.redirect("/sign-in");
}
const decode = await jwt.verify(
tokenValue.value,
process.env.TOKEN_SECRET!
);
// Check if the token has expired
if (!decode) {
return NextResponse.redirect("/sign-in");
}
const user = await fetchAdmin({ id: decode?.id });
if (!user) {
return NextResponse.redirect("/sign-in");
}
} catch (error) {
req.cookies.delete("token");
return NextResponse.redirect("/sign-in");
}
}
export const config = {
matcher: [
/*
* Match all request paths except for the ones starting with:
* - api (API routes)
* - _next/static (static files)
* - _next/image (image optimization files)
* - favicon.ico (favicon file)
/
"/((?!api|_next/static|_next/image|favicon.ico).)",
],
};
ok are loginAdminUsers and fetchAdmin in the same file?
try to put fetchAdmin in a file without importing bcrypt
Mini LopOP
no, different files
do you get an error if you comment out
const user = await fetchAdmin({ id: decode?.id });?Mini LopOP
i dont import bcrypt in fetchAdmin
try to comment out fetchAdmin and the import and see if you still get the error
Mini LopOP
it give different error when i commented it
what error?
Mini LopOP
Error: URL is malformed "/sign-in". Please use only absolute URLs - https://nextjs.org/docs/messages/middleware-relative-urls
oh ok
replace all redirect to this
return NextResponse.redirect(new URL('/sign-in', req.nextUrl));then check if you have bcrypt imported where Adminuser is
or just using bcryptjs instead of bcrypt
Mini LopOP
Ok
Im using bcrypt in different function both are in the same file
ok put fetchAdmin in a file without bcrypt imported
bcrypt does not work in middleware
Mini LopOP
Ok
Mini LopOP
TypeError: Cannot read properties of undefined (reading 'Adminuser')
This error happened while generating the page. Any console logs will be displayed in the terminal window.
This error happened while generating the page. Any console logs will be displayed in the terminal window.
oh well
i think mongo doesn't work in middleware too
try turn the fetchAdmin function into a route handler, then you can fetch it in middleware by
const user = await fetch(new URL("/api/fetchAdmin", req.nextUrl))Mini LopOP
ok
Mini LopOP
I will give you feedback