我已经构建了一个API来为登录的用户生成身份验证令牌。此时我还有一个用Node.JS编写的客户端应用程序。
当我使用用户证书从客户端应用程序向API发出请求时,我获得身份验证令牌:我应该如何将其存储在客户端应用程序中?我不应该在每次想要提供API请求时都要求提供令牌,对吗?
我想过把令牌放在Cookie中,但我不认为这是最好的解决方案。 你会推荐什么?我应该如何存储由RESTful API生成的令牌?
回答
成功登录后,一个唯一的一次性令牌应该创建在服务器端,并存储在数据库中,并与用户ID和时间戳相对应。您将令牌存储在Cookie客户端。然后您将令牌传递给每个后续的API调用。然后服务器应该检查令牌是否有效(即未过期,比如发出或更新少于30分钟前)。如果它是有效的,您可以检索针对该标记存储的用户详细信息,并执行您需要的任何后端功能(如用户的身份验证)。然后,您更新该令牌的时间戳(刷新会话,因为您希望登录在超过30分钟没有用户交互后超时)。如果您获取API调用时令牌已过期或不存在,请重定向至登录页面。
此外,您可能已经知道这一点,但要确保令牌是唯一且不可猜测的,我倾向于生成新的随机GUID并加密它们,请勿使用sequentail ID或类似的东西。
是的,我知道这个独特和不可猜测的部分,不过谢谢你指出它。我关于cookies方法的问题是,它安全吗?难道不可能窃取cookie值并访问其他用户的私人信息吗? – IgorSousaPT 2015-02-23 14:06:17
假设您使用的是SSL,那么使用中间人攻击难以理解价值。使用唯一的过期令牌会在使用后使令牌无效,所以相对安全。假设用户在会话期间保持相同的IP(可能),您也可以使用ip验证该令牌。 但是,有可能是客户端上的所有cookie信息上传至第三方网站的恶意代码,但如果正确实施,我认为使用cookie对于大多数Web应用程序来说已足够安全。或者,你可以看看OAuth,这是另一个头痛的问题,但是广泛使用的auth方法。 – 2015-02-23 14:25:19
实际上,我使用OAuth2.0来验证凭据并生成令牌。但是我仍然需要将令牌存储在客户端。除非,我得到这个非常错误! – IgorSousaPT 2015-02-23 15:04:41
我认为这个链接可以帮助你:
- 与令牌执行身份验证的RESTful应用 - https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
事实上,你应该有一个截止日期的标记,所以在发送请求之前,您不必每次都获取新令牌。当令牌过期时,您只需从服务“刷新令牌”中获取新的令牌。
关于如何将令牌存储在客户端应用程序中的问题,我认为您可以将其保存在内存(地图或嵌入式数据库)中。
否则结束,我不认为在这种用例中使用cookie是一个好主意。
希望它能帮助你。 Thierry
我们正在研究一个使用非常类似方法的应用程序。客户端应用程序是一个静态HTML5/JS单页面应用程序(不需要任何服务器端生成)并与API服务器进行通信。
最好的方法是将会话令牌存储在内存中:也就是说,在JS代码中的一个变量内。如果您的客户端应用程序是单个页面,那不应该是个问题。
除此之外,我们还将会话令牌保留在sessionStorage中以便在用户刷新页面时保留它。为了在创建新选项卡时保留标记(sessionStorage特定于浏览器窗口),我们还在关闭页面时将其存储在localStorage中,并将其与打开标签的计数器一起存储(当应用程序的所有选项卡都关闭时,我们删除令牌。
// Handle page reloads using sessionStorage
var sess = sessionStorage.getItem('session-token')
if(sess && sess !== 'null') { // Sometimes empty values are a string "null"
localStorage.setItem('session-token', sess)
}
// Set a counter to check when all pages/tabs of the application are closed
var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
counter++
localStorage.setItem('session-counter', counter)
// Event fired when the page/tab is closing
window.onbeforeunload = function() {
var counter = parseInt(localStorage.getItem('session-counter') || 0, 10)
counter--
localStorage.setItem('session-counter', counter)
// All pages are closed: remove the session token
if(counter <= 0) {
// Handle page reloads using sessionStorage
sessionStorage.setItem('session-token', localStorage.getItem('session-token'))
localStorage.removeItem('session-token')
}
}
有关的localStorage和sessionStorage的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API
为什么不饼干? Cookie不好,原因有两个: 1.它们通常更持久,可在浏览器窗口和选项卡之间共享,即使在浏览器关闭后也可以保留。 2.然而,最重要的是,根据HTTP规范,每次发出请求时都必须将它们发送到Web服务器。如果您设计的应用程序的客户端与API服务器完全分离,您不希望客户端的服务器在任何情况下都看到(或登录)会话令牌。
一些额外的建议:
- 会话令牌必须到期。您可以通过将会话令牌存储在服务器上的数据库中并在每个请求上验证它们和/或“签名”它们(以纯文本向令牌添加时间戳,然后添加签名部分(例如HMAC散列)与您只知道秘密密钥编码的时间戳)。
- 令牌可以在其生命中多次重复使用。但是,经过一定的秒数后,您可能希望服务器刷新令牌,使旧令牌失效并向客户端发送新令牌。
- 1. 应该如何存储Web API访问令牌?
- 2. 登录nodejs后生成令牌API
- 3. 我应该在本地存储由Google Web Fonts API生成的CSS吗?
- 4. 在RESTful API中存储身份验证令牌的位置
- 5. 在RESTful API中存储身份验证令牌的位置?
- 6. omniauth - 是否有任何理由为什么我应该存储在OAuth2令牌?
- 7. REST API中的令牌生成WCS
- 8. 如何将生成的不记名令牌存储到变量
- 9. 从Golang REST API生成Amazon S3令牌
- 10. 任何自由库生成令牌
- 11. 作为一个OAuth服务器,我应该如何生成和存储OAuth 2.0令牌?
- 12. 我如何从android生成JWT令牌
- 13. 如何生成oauth令牌?
- 14. OAuth:我应该在令牌中存储哪些信息
- 15. 我应该在Redis中存储JWT令牌吗?
- 16. 我应该在ID登录中持久存储ID令牌吗?
- 17. 我应该在哪里存储访问令牌
- 18. default_token_generator如何存储令牌?
- 19. Pinterest生成的令牌生存时间
- 20. 使用API的Docusign Oauth令牌生成
- 21. Microsoft Graph API使用由azure生成的令牌?
- 22. 使用令牌API失败的WSO2令牌生成
- 23. 令牌生成
- 24. 我应该如何为我的Web服务API生成文档?
- 25. 我应该在哪里保存由ASP.NET Web API动态生成的文件?
- 26. CSRF令牌生成
- 27. 生成LTPA令牌?
- 28. 使用JWT(JSON Web令牌)设置令牌的RESTful API过期
- 29. Sencha 2.0和Codeigniter RESTful API生成未捕获的SyntaxError:意外的令牌:
- 30. Rails API - 我需要存储我的Oauth2访问令牌吗?
是您的客户端应用程序,它是一个node.js服务器,使用任何数据存储? – 2015-02-23 13:36:35
我使用的是MongoDB – IgorSousaPT 2015-02-23 13:38:09
,您可以像redis一样制作内存数据存储以存储令牌并将其用于进一步请求。使用会话存储和connect-redis是一个可行的解决方案。 – 2015-02-23 13:48:56