浏览器上基于令牌的身份验证和会话/本地存储

时间:2015-01-11 14:00:56

标签: node.js session authentication cookies local-storage

好吧,我想实现一个使用身份验证机制来个性化网站用户体验的网络应用程序,但同时我还有一些问题需要清理。因此,一开始,用户将使用他们的用户名和密码登录(暂时忘记第三方认证并假设有适当的注册页面),并且在成功登录后,服务器将生成用于来自浏览器的后续调用该特定用户。在接下来的内容中,我试图验证我的理解并提出相关问题。

据我所知,在服务器端使用令牌要快得多(如果你愿意,可以减少cpu密集),因为现在一个人不必解密存储在服务器上的密码并将其与一个密码进行比较与请求一起发送(例如使用bcrypt),但检查更简单,归结为令牌是否已过期。作为额外的好处,用户名和密码的敏感信息不会重复传输。

检查点1. 当用户自愿或意外按下"刷新/重新加载"时,我们希望应用程序运行良好,以便在刷新后仍可使用该令牌(而不必再次使用凭据登录)。现在很清楚,我们必须使用cookie(即会话),或者在客户端使用会话存储或本地存储。还有另外一种方法吗?据我所知,答案是否定的(是的,本地存储有不同的选项,如Web存储,Web SQL数据库,索引数据库和文件访问,但这是不可能的)。这是对还是错?此外,在客户端处理令牌(存储/召回)最常用的做法是什么?

检查点2. 令牌过期。据我所知,这个想法是,每次使用有效令牌时,该特定令牌的到期时间都会更新(比如7或10天后)。这样做的好处是,定期访问该站点的用户只需登录一次。但缺点似乎是暗示令牌对同一用户保持不变 - 可能永远 - 但除非令牌过期。那么问题是,这样安全吗?这里的另一个想法是更新后端的令牌,在客户端发送更新的令牌并更新浏览器本地存储上的令牌,而所有内容对最终用户都是透明的。这是一种常见做法吗?我可以看到,现在在服务器端,需要对生成的令牌保持谨慎(参见下面的场景)。是否有处理这种情况的常见做法(如果需要处理它)?

(假设用户A有两个设备A1和A2,使用令牌TA1,从现在起7天后到期,用户B使用令牌TB1的设备B1,从现在起7天后到期。所有令牌都存储在某种类型的本地存储。六天后(即实际到期前一天),TA1更新为TA2,而用户A使用设备A1。同样,当天TB1更新为TA1。现在如果用户A使用设备A2,那么有一个有效的令牌(TA1),但在使用API​​时将作为用户B进行身份验证!)

Checkpoint 3。我一直认为基于令牌的身份验证就是这样。通过http请求的标头发送的单个令牌,即全部。显然,如果一个人也发送用户名,那么我们就避免发送密码,我们也避免了上面描述的有问题的情况。但是,我不喜欢这种方法。毕竟,现在令牌充当密码。唯一的保存是解密(即cpu-cycles),同时匹配服务器端的凭证。这种方法是废话还是什么?

Checkpoint 4。如果将来有人想创建一个专用智能手机或平板电脑的应用程序,那么(据说)在请求标题上使用令牌会更容易,而不是依赖cookie和会话(参见cookie容器)。这对我来说很轻微,但这是真的吗?

我认为上述问题与实现无关,但如果您想为开发提供指导,我将使用node.js。

1 个答案:

答案 0 :(得分:3)

1:Cookie是存储令牌客户端的首选方法。

2:您可以重新授权用户并发回更新的令牌,或者只是延迟令牌的到期时间。这在很大程度上取决于您如何存储令牌,并且正在处理到期机制(例如,Mongo的生存时间机制,或SQL数据库中的&expreeAt'字段等) 。通过正确的令牌生成,用户劫持另一个用户的会话时概述的场景不可能。

3:令牌应该是授权用户所需的唯一标记。在服务器端,一旦获得令牌,您只需执行操作即可检索用户对象。这在很大程度上取决于您如何设置系统。例如,您可以对其进行设置,以便将签名的令牌直接解码为用户对象,或者如果您使用持久存储来存储令牌,则使用该令牌作为查询中的键。

4:发送令牌时,无论平台如何,您最好使用请求的标头。 Cookie,本地存储等仅仅是将令牌保存在用户设备上的工具。

如果你正在为你的应用程序使用Node.js,我建议在angular-fullstack中查看auth的处理方式,该方式使用Passport,其外部承载策略类似于你所使用的策略。重新尝试。