因此,我一直在尝试使用 cookie 对 React 应用程序实施某种基于角色的访问控制。
但我似乎误解了它的用途。 这个想法是有一个上下文来获取存储在 cookie 中的信息,这意味着它将有一个专门的 API 端点,仅用于检查存储在 cookie 中的值。
除了上下文从头到尾启动之外,应用程序已运行。 正确登录后在后端仍然没有收到所述cookie。
即使它已正确发送到浏览器。
我不知道为什么没有正确发送cookie,也不知道如何使上下文查询仅在正确登录时触发。
这些是一些相关的终点:
//cookie是如何创建的以及登录时给出的信息
const token = jwt.sign( { medicoInfo: { username: medico.username, especialidad: medico.especialidad, }, }, jwtSecret, { expiresIn: "1d", } ); res.cookie("auth_cookie",token,{ httpOnly: true, secure: false, //Becouse of the localhost maxAge: 24 * 60 * 60 * 1000 }) res.json({token});
//检查前端中角色的AuthContext
const AuthContext = createContext<string[] | undefined>(undefined);
export const AuthContextProvider = ({children} :{children: ReactNode})=>{
const {data:roles} = useQuery({
queryFn: ()=> fetchRole(),
queryKey: ["roles"],
})
const userRoles = roles || [];
return(
<AuthContext.Provider value={userRoles}>
{children}
</AuthContext.Provider>
)
}
export const useAuthContext = ()=>{
const context = useContext(AuthContext);
return context;
}
// 前端 API
export const fetchRole = async ():Promise<string[]>=>{
const response = await fetch("http://localhost:3000/api/auth/check-role",{
credentials: "include",
});
if (!response.ok) {
throw new Error("Something went wrong...");
}
return response.json();
}
//后端API
//路线
authRoutes.get('/check-role',verifyToken,async ( req:Request, res:Response)=>{
res.status(200).send({userRole: req.userInfo.especialidad});
})
// verifyToken 中间件
declare global{
namespace Express{
interface Request{
userInfo: {
username: string,
especialidad: string[],
}
}
}
}
const verifyToken = (req: Request, res: Response, next: NextFunction)=>{
console.log(req.cookies);
const token = req.cookies["auth_cookie"];
if(!token){
return res.status(401).json({message: "Unauthorized"});
}
try {
const decoded = jwt.verify(token, process.env.JWT_SECRET as string);
req.userInfo = (decoded as JwtPayload).userInfo;
next();
} catch (error) {
return res.status(401).json({message: "Unauthorized"});
}
}
我仍在学习 React 以及前端和后端的通信方式,因此非常感谢任何反馈,而且将角色保存在上下文中的想法是我计划在组件内同时拥有受保护的路由和显示,所以我想了想最好在后端中指定角色或 especialidad,这是在授予授权时要记住的参数,存储在上下文中。
所以是的...我感谢您花时间阅读我的文章,正如我所说,任何反馈都是值得赞赏的。谢谢!
正确登录后端后仍然没有收到所述cookie。
可能原因:
1. 您的 Express 服务器中没有 cookie 解析器。您可以使用 cookie-parser npm 包并将其添加到您的中间件中。
2. 使用此 cors npm 包发送/接收跨源 cookie(意味着当您的前端和后端分离时),您的后端必须有 cors 配置。
您的 cors 包的配置:
app.use(cors({
origin: "put your client's url here",
credentials: true
}))
我还注意到您错误地访问了令牌的属性:
const verifyToken = (req: Request, res: Response, next: NextFunction)=>{
...
const decoded = jwt.verify(token, process.env.JWT_SECRET as string);
req.userInfo = (decoded as JwtPayload).userInfo;
next();
...
}
您生成的令牌中不存在 userInfo 属性:
const token = jwt.sign(
{
medicoInfo: {
username: medico.username,
especialidad: medico.especialidad,
},
},
...
);
您应该将其替换为 medicoInfo
...
req.medicoInfo = (decoded as JwtPayload).medicoInfo;
...
// and in your route
authRoutes.get('/check-role',verifyToken,async ( req:Request, res:Response)=>{
res.status(200).send({userRole: req.medicoInfo.especialidad});
})