I return the access token
and some user data in the response while setting the refresh token
in an HTTP-only cookie
on the server when the user logs in.
However, the refresh token
is not being set in the cookie
because the login request is made from a client component, while auth.js
needs to work in a server component.
Problem
The refresh token
does not get stored in the HTTP-only cookie
.
I suspect this is because the request is coming from a client component, while the authentication logic (auth.js
) needs to work in a server component
.
What I'm Looking For
- How can I properly store the
refresh token
in anHTTP-only cookie
while usingserver components
? - Is there a better approach to handle authentication in
Next.js
14+** withserver components
? - Any recommended articles, books, or courses that explain secure token storage and best practices against
XSS
,CSRF
, etc.?
My Current Approach
I'm using a signinUser
function that makes a request to the /auth/login
API:
// login.js
import api from "@/utils/api";
export async function signinUser({ username, password }) {
try {
const response = await api.post(
`/auth/login`,
{ username, password },
{ withCredentials: true } // Ensures cookies are sent
);
return { data: response.data, success: "success" };
} catch (error) {
const errorMessage =
error.response?.data?.message ||
error.response?.data?.error ||
error.response?.data?.errors?.[0]?.msg;
return { error: errorMessage || "An error occurred. Please try again." };
}
}
I return the access token
and some user data in the response while setting the refresh token
in an HTTP-only cookie
on the server when the user logs in.
However, the refresh token
is not being set in the cookie
because the login request is made from a client component, while auth.js
needs to work in a server component.
Problem
The refresh token
does not get stored in the HTTP-only cookie
.
I suspect this is because the request is coming from a client component, while the authentication logic (auth.js
) needs to work in a server component
.
What I'm Looking For
- How can I properly store the
refresh token
in anHTTP-only cookie
while usingserver components
? - Is there a better approach to handle authentication in
Next.js
14+** withserver components
? - Any recommended articles, books, or courses that explain secure token storage and best practices against
XSS
,CSRF
, etc.?
My Current Approach
I'm using a signinUser
function that makes a request to the /auth/login
API:
// login.js
import api from "@/utils/api";
export async function signinUser({ username, password }) {
try {
const response = await api.post(
`/auth/login`,
{ username, password },
{ withCredentials: true } // Ensures cookies are sent
);
return { data: response.data, success: "success" };
} catch (error) {
const errorMessage =
error.response?.data?.message ||
error.response?.data?.error ||
error.response?.data?.errors?.[0]?.msg;
return { error: errorMessage || "An error occurred. Please try again." };
}
}
Share
Improve this question
edited Mar 20 at 23:13
Hilory
2,1417 gold badges14 silver badges30 bronze badges
asked Mar 20 at 22:56
user30005873user30005873
1
1 Answer
Reset to default 0The issue is that your client component can't set HTTP-only cookies directly. Here's the simplest solution:
1. Change your:
// app/api/auth/login/route.js
import { NextResponse } from "next/server";
export async function POST(request) {
try {
const { username, password } = await request.json();
// Call your actual auth API/service
const authResponse = await fetch('https://your-auth-api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
const authData = await authResponse.json();
if (!authResponse.ok) {
return NextResponse.json({ error: authData.message }, { status: 401 });
}
// Create response with access token and user data
const response = NextResponse.json({
user: authData.user,
accessToken: authData.accessToken
});
// Set HTTP-only cookie with refresh token
response.cookies.set({
name: "refreshToken",
value: authData.refreshToken,
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 7, // 7 days
path: "/",
});
return response;
} catch (error) {
return NextResponse.json({ error: "Server error" }, { status: 500 });
}
}
2. Create a server-side route handler:
// app/api/auth/login/route.js
import { NextResponse } from "next/server";
export async function POST(request) {
try {
const { username, password } = await request.json();
// Call your actual API/service
const authResponse = await fetch('https://your-auth-api/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username, password }),
});
const authData = await authResponse.json();
if (!authResponse.ok) {
return NextResponse.json({ error: authData.message }, { status: 401 });
}
// Create response
const response = NextResponse.json({
user: authData.user,
accessToken: authData.accessToken
});
// Set HTTP-only cookie
response.cookies.set({
name: "refreshToken",
value: authData.refreshToken,
httpOnly: true,
secure: process.env.NODE_ENV === "production",
sameSite: "strict",
maxAge: 60 * 60 * 24 * 7, // 7 days
path: "/",
});
return response;
} catch (error) {
return NextResponse.json({ error: "Server error" }, { status: 500 });
}
}
The key points here:
Your client-side code stays almost the same but calls your Next.js API route The route handler makes the actual auth request to your backend The route handler sets the HTTP-only cookie using response.cookies.set() The access token is returned in the JSON response for use in memory
This approach is secure because:
Refresh token is stored in an HTTP-only cookie (protected from XSS), access token is stored in memory only (not localStorage), Next.js route handlers run on the server and can set proper HTTP-only cookies
You can implement similar route handlers for token refresh and logout operations following the same pattern. Wish you'r code the best!
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744380518a4571405.html
评论列表(0条)