如果使用 JWT,如何保护来自访客和角色的路由?
Posted
技术标签:
【中文标题】如果使用 JWT,如何保护来自访客和角色的路由?【英文标题】:How to protect routes from guests and with roles if using JWT? 【发布时间】:2021-10-10 22:05:06 【问题描述】:在服务器端,我有 2 个中间件 - Protect(已登录?)和 restrictTo(检查用户角色)。如果不允许用户或访客执行某些操作,这些中间件会阻止他们执行某些操作
exports.protect = catchAsync(async (req, res, next) =>
let token;
if (
req.headers.authorization && req.headers.authorization.startsWith("Bearer")
)
token = req.headers.authorization.split(" ")[1];
if (!token)
return next(new AppError("You are not signed in!", 401));
const decodedToken = await promisify(jwt.verify)(
token,
process.env.JWT_SECRET
);
const currentUser = await User.findById(decodedToken.id);
if (!currentUser)
return next(new AppError("User with such token no longer exists"));
req.user = currentUser;
next();
);
exports.restrictTo = (...roles) =>
return (req, res, next) =>
if (!roles.includes(req.user.role))
return next(new AppError("No access", 403));
next();
;
;
但是如何保护客户端的路由呢?如果不允许我发布新笔记,那么我应该被阻止进入 /newnote 页面,这样我就无法查看和填写表格。 JWT 令牌存储在带有 httpOnly 标志的 cookie 中。所以我无法从 Vue 路由器访问令牌。在 Vuex 中存储用户的角色?那么如何在 cookie 和 Vuex 中同步令牌状态呢?如果我的令牌在服务器端被销毁,我仍然可以在 Vuex 中使用它,直到我向受保护的端点发送请求。 我应该为受保护的路由请求一个特殊的身份验证端点,以使用 beforeEach 检查我当前的角色吗?
【问题讨论】:
【参考方案1】:基本上,你应该添加两件事:
存储当前经过身份验证的用户。默认情况下,authUser 为空。当有人登录时,authUser 是一个包含用户数据的对象。您可以将其存储在 Vuex、localStorage 等中。 在您用于 api 请求的任何库中创建一个拦截器/中间件。如果在某个时候您收到 401/403,则表示当前用户的会话已过期,或者他正在尝试访问他不应该查看的受保护区域。无论哪种方式,将本地 authUser 重置为 null 并重定向到登录。在 Spa/mobile 中,只要您的后端得到适当保护,您就不必为此担心太多。如果您的 authUser 逻辑是正确的,那么只有怀有恶意的用户才会尝试访问保护区,而普通用户将按照规则进行操作,并且永远不会以他们当前的权限访问他们不应该访问的页面(假设 UI 连接正确...... )。
【讨论】:
以上是关于如果使用 JWT,如何保护来自访客和角色的路由?的主要内容,如果未能解决你的问题,请参考以下文章