[英]Set-Cookie sent by express-sessions is not being set on browser but works in local development
我有一個當前托管在 Vercel 上的 nextjs 13 應用程序,以及一個 node.js 快遞后端
我正在使用 express-sessions 和 google oauth flow,但是 express-sessions 發送的 set-cookie 沒有在瀏覽器上設置。
流程如下:
req.session
上,並使用set-cookie
再次重定向到 nextjs 應用程序這是后端發送的響應:
快速會話中間件的設置:
app.use(
session({
name: 'sessionID',
cookie: {
maxAge: SESSION_LIFETIME as number,
sameSite: 'lax',
secure: NODE_ENV === 'production',
httpOnly: true
},
resave: false,
secret: SESSION_SECRET as string,
saveUninitialized: false,
store: redisStore
})
);
谷歌 OAuth 回調代碼:
try {
const query = url.parse(request.url, true).query as {
code: string;
};
const { tokens } = await googleOauth.getToken(query.code);
const { access_token, refresh_token } = tokens;
const userInfoResponse = await fetch(
`https://www.googleapis.com/oauth2/v1/userinfo?alt=json&access_token=${access_token}`
);
const { email } = await userInfoResponse.json();
let user = await getUserByEmail(email);
if (user === undefined) {
response.writeHead(307, { Location: process.env.WEB_URL + '?error=failed' });
response.end();
return;
}
// If it's the first time user logged in, create an account
if (user === null) {
user = await createUser({ email });
// Something went wrong when creating the user
if (!user) {
response.writeHead(307, { Location: process.env.WEB_URL + '?error=failed' });
response.end();
return;
}
}
const userToken = await saveUserTokens(
user.id,
access_token as string,
refresh_token as string,
OAuthProvider.google
);
if (!userToken) {
response.writeHead(307, { Location: process.env.WEB_URL + '/?error=true' });
response.end();
return;
}
request.session.userId = user.id.toString();
response.redirect(307, process.env.WEB_URL as string);
} catch (error) {
logger.error('Error while logging in with google', error);
response.writeHead(307, { Location: process.env.WEB_URL + '/?error=true' });
response.end();
}
我認為這可能是由於發生了幾次重定向? 我有另一個端點用於使用 email 和帶有快速會話的密碼進行身份驗證,並且成功設置了該響應發送的 set-cookie。 這是 email 和密碼驗證的 /login 路由的響應:
登錄處理程序(電子郵件 + 通行證)代碼:
const loginHandler: RequestHandler = async (request, response) => {
const { email, password } = request.body;
const isValid = is(email, Email) && is(password, Password);
if (!isValid) {
return response
.status(StatusCodes.BAD_REQUEST)
.send({ message: 'Invalid Request: Missing or invalid email and password.' });
}
const user = await getUserByEmail(email);
if (!user) {
return response.sendStatus(401);
}
// Check if user logged in previously with another provider
if (!user.password) {
return response
.status(StatusCodes.BAD_REQUEST)
.send({ message: 'Please login with the login provider you used previously' });
}
const isPasswordCorrect = await compare(password, user.password);
if (!isPasswordCorrect) {
return response.sendStatus(StatusCodes.UNAUTHORIZED);
}
request.session.userId = user.id.toString();
response.sendStatus(StatusCodes.OK);
};
如果您的前端和后端是獨立的域,請嘗試像這樣再次設置您的 cookie:
app.use(
session({
name: 'sessionID',
cookie: {
maxAge: SESSION_LIFETIME as number,
sameSite: 'none', // in order to response to both first-party and cross-site requests
secure: 'auto', // it should set automatically to secure if is https.
httpOnly: true
},
resave: false,
secret: SESSION_SECRET as string,
saveUninitialized: false,
store: redisStore
})
);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.