客户端是不是应该在每条路由上进行身份验证? [关闭]
Posted
技术标签:
【中文标题】客户端是不是应该在每条路由上进行身份验证? [关闭]【英文标题】:Should the client authenticate on every route? [closed]客户端是否应该在每条路由上进行身份验证? [关闭] 【发布时间】:2020-11-16 02:35:50 【问题描述】:localStorage 中有一个 JWT。
假设用户转到app.com/accounts
。
JWT 被发送到后端app.com/api/accounts
获取数据,在到达之前,它会在身份验证中间件中进行检查。
后端
let authenticationMiddlewareBackend = (req, res, next) =>
let token = req.headers.authorization;
jwt.verify(token, "secret", (err, decoded) =>
if (err)
res.status(401)
else
req.decoded = decoded;
next();
);
;
app.all("/api/*", authenticationMiddlewareBackend);
现在可以了。问题是,客户端是否应该在到达app.com/accounts
之前也这样做?
客户
async function authenticationMiddlewareClient(next)
if (window.location.pathname != "/login")
let verifyResponse = await (
await fetch(`/verify`,
method: "GET",
withCredentials: true,
credentials: "include",
headers:
Authorization: localStorage.getItem("token"),
Accept: "application/json",
"Content-type": "application/json",
,
)
).json();
if (verifyResponse.isAuthenticated)
next();
else
page("/login");
else
next();
page("*", authenticationMiddlewareClient);
后端
router.get("/verify", async function (req, res)
try
let token = req.headers.authorization;
jwt.verify(token, "secret", (err, decoded) =>
if (err)
res.status(401)
else
res.status(200).send( isAuthenticated: true, ...decoded );
);
catch (err)
next(err);
);
客户端是否应该将身份验证结果存储在一个变量中,而不是每次都发出验证请求?我不确定这是否可以被某种方式利用。
【问题讨论】:
我不认为每次都需要它。当经过身份验证的请求因 401 错误而失败时,前端可以理解令牌无效/过期,然后删除令牌。所以,我认为不需要每次都验证。 我不太明白你的意思。你能澄清一下吗?我仍然需要每次发送请求以检查有效性。 我的意思是,登录时生成的令牌可能会存储在本地存储中,无需验证即可用于后续结果。 (在第一页加载时验证它可能是个好主意)。之后无需再次验证令牌,因为如果任何其他请求失败,玩具将收到401
错误。因此,如果出现 401 错误,请从本地存储中删除令牌并将用户重定向到登录页面。
我明白了。我的困惑是,如果有人放置具有isAuthenticated: true
属性的虚构令牌,他们就可以访问该应用程序。另外,我怎么知道这是第一个页面加载?
即使他们添加了一个伪造的令牌,他们也无法进行任何操作,对吧。此外,当他们尝试执行操作(向后端发出请求)时,您会将他们重定向到登录,因为假令牌被后端发现并发送 401
。
【参考方案1】:
最好在 App 加载时检查令牌,而不是在每个路由器上检查。 Token 会被后端 API 检查,你可以通过检查状态码是否为 401 来验证。
【讨论】:
【参考方案2】:不需要单独的 API 调用,因为它不会为流程增加任何安全性或效率。只需在处理任何数据之前检查中间件中的 JWT,就像您在第一个文件中所做的那样。
【讨论】:
跟进:为什么您认为可能需要单独进行? 我不知道。我不知道如何限制对应用程序本身的访问。我应该在渲染路由之前检查isAuthenticated
布尔值的令牌内容吗?是什么阻止了某人将假令牌放入 localStorage 以获取应用程序的访问权限?
如果令牌是假的,那么你的中间件就会知道。你有一个秘密,没有人知道(希望如此),所以他们无法生成符合你秘密的明智 JWT
这是我的问题。 “如果令牌是假的,那么你的中间件会知道。” 是说我仍然需要向/verify
后端路由发出请求以检查有效性,这就是我正在做的事情.令牌只是base64,中间部分可以伪造,因为客户端没有办法检查有效性,每次需要路由时都没有请求。
不,但是中间件会处理这个,所以你不需要在单独的调用中这样做。如果用户想要... 发布图片,但需要登录:他们发布图片,负载中包含 JWT,以便后端可以读取它,验证用户的授权,然后将图片发送到该过程的下一部分。如果您在单独的调用中执行此操作,则用户可以简单地在客户端伪造“成功”部分,因此最好在中间件中执行此操作。以上是关于客户端是不是应该在每条路由上进行身份验证? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
C# SMTP 无法在 Outlook.com 端口 587 上进行身份验证。“服务器响应为:5.7.1 客户端未通过身份验证”
静默刷新在 OPTIONS 预检上进行身份验证,但不在 GET 到 UserInfo 端点上进行身份验证