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

好吧,我想实现一个networking应用程序,使用身份validation机制来个性化网站上的用户体验,但同时我有一些问题,我想清除。 因此,一开始,用户将以他们的用户名和密码login(现在让我们忘记第三方authentication,并假设有一个适当的注册页面),并成功login后,服务器将生成一个令牌,用于从该特定用户的浏览器。 接下来,我正试图validation我的理解并提出相关的问题。

据我所知,在服务器端使用令牌的速度要快得多(如果你愿意的话,cpu密集程度要低一些),因为现在不需要解密存储在服务器上的密码,并将其与使用请求(例如使用bcrypt ),但相反,检查要简单得多,归结为令牌是否过期。 作为额外的好处,用户名和密码的敏感信息不会重复传输。

检查点1.我们希望应用程序在用户自愿或不小心按下“刷新/重新加载”时强健,这样令牌在刷新后仍然可以使用(而不必再用凭证login)。 现在很清楚,要么我们必须使用cookie(即会话),要么在客户端使用会话存储或本地存储。 有另一种方法吗? 据我所知,答案是否定的(是的,本地存储有不同的select,如Web存储,Web SQL数据库,索引数据库和文件访问,但这是超出了问题)。 这是对还是错? 而且,在客户端处理令牌(存储/调用)最常用的做法是什么?

检查点2.令牌到期。 据我所知,这个想法是,每次使用有效的令牌时,该特定令牌的到期时间被更新(例如7或10天后)。 这对于定期访问该站点的用户仅需要login一次就具有很好的好处。 但是,不利之处似乎在于,对于相同的用户,令牌保持不变 – 可能永远不变(除非令牌过期)。 那么问题是,这是安全的吗? 这里的另一个想法是更新后端的令牌,在客户端发送更新的令牌,更新浏览器的本地存储器上的令牌,而对最终用户而言,所有内容都是透明的。 这是常见的做法吗? 我可以看到,现在在服务器端,需要对生成的令牌保持谨慎(请参阅下面的场景)。 是否有共同的做法来处理这个(如果需要处理的话)?

(假设用户A有两台设备A1和A2,使用令牌TA1,从现在开始7天到期,用户B有设备B1使用令牌TB1,从现在起7天后到期,所有的令牌都存储在某种本地存储器中。六天后(即实际到期前一天),当用户A正在使用设备A1时,TA1更新为TA2,同样在当天,TB1更新为TA1,现在如果用户A使用设备A2,令牌(TA1),但在使用API​​时将以用户B身份进行身份validation!)

检查点3.我一直认为基于令牌的authentication就是这样。 通过http请求的头部发送一个令牌,这就是全部。 显然,如果你也发送用户名,那么我们就避免发送密码,而且我们也避免了上述的问题。 不过,这种方法我不太喜欢。 毕竟,现在令牌作为一个密码。 唯一的节省是在服务器端匹配证书时的解密(即cpu-cycles)。 这种方法是废话还是什么?

检查点4.如果将来想创build智能手机或平板电脑的专用应用程序,则在请求的标题上使用标记(应该是非常容易),而不是依赖于Cookie和会话(请参阅cookie容器) 。 目前这对我来说很小,但这是真的吗?

我认为上面的问题是实现不可知的,但是如果你想给开发指针,我将使用node.js。

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

2:您可以重新授权用户并发送更新的令牌,也可以延迟令牌的到期。 这在很大程度上取决于你如何存储令牌,并处理到期机制(例如,Mongo的生存时间机制,或SQL数据库中的'expiresAt'字段等)。 当用户劫持另一个用户的会话时,您所概述的情况不应该可以通过正确的令牌生成来实现。

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

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

如果您使用Node.js作为您的应用程序,那么我build议您检查一下auth是否在使用与您正在尝试执行的操作类似的外部承载策略的Passport中使用Pass-fullstack的方式。