对于我目前正在进行的一个项目,我正在使用 Node/Express/Mongo 开发一个 API,并使用相同的工具单独开发一个网站。理想情况下,我希望将它们托管在单独的服务器上,以便可以根据需要进行扩展。
对于身份验证,我使用 jsonwebtoken我已经设置了它,并且总体上我对它的工作方式感到满意。
但是...
在网站上,我希望能够限制(使用 Express)经过身份验证的用户的某些路由,但我在寻找实现此目的的最佳方法方面遇到了一些困难。该 token 当前保存在 LocalStorage 中。
我认为我可以通过 get 参数将 token 传递到我想要保护的任何路由,然后在网站服务器上检查此 token (显然这意味着这里也包含 jwt secret ,但我没有看到一个大问题那个)。
所以我的问题是
- 这行得通吗?
- 这是否意味着(没有双关语)我最终会得到丑陋的网址
- 我是否可以更好地将两者托管在同一服务器上,然后将生成的 token 保存在服务器端?
- 有更好的解决方案吗?
我应该说我不想使用 Angular - 我知道这会解决我的一些问题,但它会给我带来更多问题!
最佳答案
首先,我将直接回答您的问题:
- 这行得通吗?是的,它会起作用。但也有很多缺点(更多讨论见下文)。
- 不一定。我真的不认为丑陋的网址包含查询字符串。但无论如何,所有身份验证信息( token 等)都应包含在 HTTP 授权 header 本身中,而不是包含在 URL(或查询字符串)中。
- 这对于您的情况来说并不重要,因为只要您的 JWT 生成代码具有与网络服务器相同的 key ,您就可以验证 token 的真实性。
- 是的!请阅读下文。
现在我们已经解决了这些问题,让我解释一下为什么您所采取的方法目前不是最好的主意(不过,您离一个好的解决方案并不遥远! ):
首先,由于存在 XSS(跨站脚本攻击),目前将任何身份验证 token 存储在本地存储中并不是一个好主意。本地存储不提供任何形式的域限制,因此您的用户可能会很容易被欺骗而放弃他们的 token 。
这里有一篇好文章,以易于理解的形式详细解释了为什么这是一个坏主意:http://michael-coates.blogspot.com/2010/07/html5-local-storage-and-xss.html
您应该做什么:将您的 JWT 存储在经过签名和加密的客户端 cookie 中。在 Node 世界中,有一个优秀的 mozilla session 库可以自动为您处理此问题:https://github.com/mozilla/node-client-sessions
接下来,您永远不想通过查询字符串传递身份验证 token (JWT)。原因有以下几个:
- 大多数网络服务器都会记录所有网址请求(包括查询字符串),这意味着如果任何人掌握了这些日志,他们就可以作为您的用户进行身份验证。
- 用户在查询字符串中看到此信息,它看起来很难看。
相反,您应该使用 HTTP 授权 header (这是一个标准)来向服务器提供您的凭据。这有很多好处:
- 网络服务器通常不会记录此信息(没有困惑的审计跟踪)。
- 许多标准库都可以解析此信息。
- 最终用户在随意浏览网站时不会看到此信息,并且不会影响您的网址模式。
假设您使用 OAuth 2 不记名 token ,您可以按如下方式制作 HTTP 授权 header (假设您将其表示为 JSON blob):
{“授权”:“此处为承载者 myaccesstoken”}
现在,最后,如果您正在寻找上述实践的良好实现,我实际上在 Node 中编写并维护了一个更流行的身份验证库:stormpath-express .
它以干净、经过良好审核的方式处理上述所有用例,并且还提供了一些方便的中间件来自动处理身份验证。
这里是中间件实现的链接(您可能会发现这些概念很有用):https://github.com/stormpath/stormpath-express/blob/master/lib/authentication.js
apiAuthenticationRequired
中间件本身非常好,因为如果用户未通过 API 身份验证(HTTP 基本身份验证或带有不记名 token + JWT 的 OAuth2)正确进行身份验证,它将拒绝用户的请求.
希望这有帮助!
关于node.js - JSON Web token 身份验证服务 - 检查单独服务器上的状态以保护路由。 NodeJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28371662/