登录后Set-Cookie未在后续请求中携带的授权问题排查
问题背景
我实现了一套登录流程:用户登录成功后,后端通过响应头的Set-Cookie字段设置Cookie;后端同时配置了认证中间件,每次接收HTTP请求时校验该Cookie。目前客户端登录后已成功存储Cookie,但发起后续请求时Cookie丢失,服务器判定新请求为未授权请求。
相关信息
登录后的响应头描述
响应头中包含Set-Cookie字段,键为Authorization,附带HttpOnly、Secure、SameSite等属性。
登录后新请求的请求头描述
请求头中未携带任何Cookie字段。
相关代码
后端登录接口(设置Set-Cookie)
public logIn = async (req: Request, res: Response, next: NextFunction) => { const logInData: LogInDto = req.body; const user: UserInterface = await this.User.findOne({ email: logInData.email }); if (user) { console.log(user); const passwordMatch: boolean = await this.authService.matchPassword(logInData, user); console.log(passwordMatch); if (passwordMatch) { const token: Token = this.authService.createToken(user); const cookie: any = this.authService.createCookie(token); res.setHeader("Set-Cookie", [cookie]); res.status(200).json( { message: "Login success", user: user } ); } else { next(new CredentialsException()); } } else { next(new CredentialsException()); } }
客户端登录后新请求代码
const Dashboard: React.FC = () => { const handleClick = async () => { const res: any = await axios.get<any>( "http://localhost:4000/getusers", { withCredentials: true } ); console.log(res); } }
后端认证中间件代码
export async function authMiddleware(req: Request, res: Response, next: NextFunction) { console.log(req.cookies); const cookies: any = req.cookies; if (cookies && cookies.Authorization) { const pubKey: string | Buffer = fs.readFileSync("./server.public.key", "utf8"); try { let verifyOptions: any = { algorithm: ["RS256"] }; const tokenPayload: TokenPayload = jwt.verify(cookies.Authorization, pubKey, verifyOptions) as unknown as TokenPayload; const _id: string = tokenPayload._id; const user: UserInterface | null = await User.findById(_id); if (user) { req.user = user; next(); } else { next(new AuthTokenException()) } } catch (error) { next(new AuthTokenException()); } } else { next(new AuthTokenException()); } }
客户端登录请求代码
export const login = createAsyncThunk( "auth/login", async (loginData: LoginData, thunkAPI: any) => { try { const { email, password } = loginData; const { data: resData, headers: resHeaders } = await axios.post<LoginResponse>( "http://localhost:4000/login", { email: email, password: password, }, ); console.log(resData); console.log(resHeaders); return resData; } catch (error: any) { console.log(error.message); console.log(thunkAPI.rejectWithValue(error.message)); return thunkAPI.rejectWithValue(error.message); } } )
解决方案
你不需要额外设置请求头,问题出在以下几个核心点,逐一排查即可:
登录请求未开启凭证携带
客户端登录请求没有配置withCredentials: true,导致浏览器未保存后端设置的Cookie。修改登录请求代码:const { data: resData, headers: resHeaders } = await axios.post<LoginResponse>( "http://localhost:4000/login", { email, password }, { withCredentials: true } // 新增该配置 );Cookie的SameSite属性配置冲突
若Cookie的SameSite设置为Strict或Lax,前后端端口/域名不一致时,跨域请求会自动丢弃Cookie。需在后端调整Cookie配置:// 示例createCookie方法中的配置 return `Authorization=${token}; HttpOnly; Path=/; SameSite=None; ${process.env.NODE_ENV === 'production' ? 'Secure' : ''}`;注:
SameSite=None必须搭配Secure属性,本地开发用HTTP时可临时关闭Secure,生产环境必须开启。后端跨域配置未允许凭证
后端需配置CORS允许携带凭证,以cors中间件为例:app.use(cors({ origin: 'http://localhost:3000', // 前端实际地址 credentials: true }));
内容的提问来源于stack exchange,提问作者code_learner93
相关产品推荐
相关产品推荐

