我在Express中有一个服务器,它向web应用程序公开一些API。我正在寻找一个好的方式来管理双方的最终用户和第三方认证。
现在,当用户使用电子邮件和密码注册时,服务器将生成一个与该用户相关联的JWT。
function createToken(user, role) {
var usr = {
role: role, // admin | customer | shop
email: user.email,
name: user.name
};
var expires = (Date.now() / 1000) + 60 * 60 * 24 * 365; // 1 year
var nbf = Date.now() / 1000;
usr['nbf'] = nbf;
usr['exp'] = expires;
var token = jwts.encode(usr, process.env.SECRET);
return token;
}当web客户机接收到该令牌时,它会将令牌存储在cookie/web_storage中,并将其用于对服务器的每个API调用以及自动登录。令牌还包含role,因此当服务器收到请求时,它知道该用户/角色是否可以访问所请求的路由/资源。
function checkToken(token, api_name) {
// verifies secret and checks exp
jwt.verify(token, process.env.SECRET,
function (err, decoded) {
if (err) { throw { msg: "token expired or not authenticated", code: errors.ERR_NOT_AUTH }; }
else {
var role = decoded['role'];
return does_role_can_access_api(role, api_name); // true or false
}
});
}现在,一些第三方想要访问,一些我的API的。我想为想要使用我的服务器的应用程序创建一个速成网关,并为单个用户保留现有的JWT身份验证。
所以我会
|----------------|
| my Web-App |
|----------------|----> |------------| |------------|
| Express | | my Server |
| Gateway |----------> | APIs |
|----------------|----> |------------| |------------|
| 3rd party |
|----------------|admin(像我一样)和我们的用户(customers和shops)所使用。customers和shops。所以我想做这样的事情:
|----------------|
| my Web-App |
| scopes: |
| [admin, user] |
| |
|----------------|----> |------------| |------------|
| Express | | my Server |
| Gateway |----------> | APIs |
|----------------|----> |------------| |------------|
| 3rd party |
| scopes: |
| [user] |
|----------------|最后,我的Web将有一个包含所有作用域的ApiKey,而第三方ApiKeys将只有user作用域,因此我可以在上面筛选路由。无论应用程序是什么,单个真正的用户都将使用JWT令牌登录并发出请求。
因此,每个请求都有一个ApiKey (基于所使用的应用程序)和一个JWT令牌(用于标识用户):
听起来不错吗?
发布于 2020-02-21 15:12:53
首先,对您在开发安全应用程序方面所做的一切表示祝贺,因为我们并不是每天都看到开发人员这么做。
澄清可能存在的误解
在我深入讨论您的问题之前,我想先澄清一个误解,即开发人员通常会对、和访问他们的后端的有什么看法。在这篇文章中详细讨论了这一点,在这里我们可以阅读:
什么是,向API服务器发出请求的事情。它真的是你的移动应用程序的真实实例,还是一个机器人,一个自动脚本,还是一个攻击者用一个像邮递员这样的工具手动地在你的API服务器上穿插? who是移动应用程序的用户,我们可以通过多种方式验证、授权和识别该应用程序,比如使用OpenID连接或OAUTH2流。
虽然本文是在移动应用程序的上下文中,但是为了理解和访问API服务器之间的区别,对mobile app的引用可以用web app代替。如果你偷有疑问,请去阅读链接文章的章节,这也包括一个图形,以帮助理解这一点。
你的问题
现在,当用户使用电子邮件和密码注册时,服务器将生成一个与该用户相关联的JWT。 var = (Date.now() / 1000) + 60 * 60 * 24 * 365;// 1年 我的Web应该访问所有的App,因为我的Web被管理员(像我一样)和我们的用户(客户和商店)所使用。
这是渴望身份验证令牌的方式,特别是当您说API是由管理员访问的时候,但是即使对普通用户来说也太长了。
根据您的用例,我建议它们在分钟范围内,因此我建议您切换到使用刷新令牌,这将使访问令牌保持较短的寿命,而刷新令牌可以使用很长时间,但在小时范围内,而不是在几天、几周或几年内。
刷新令牌流示例:

注意事项:虽然上面的图形属于在移动API上下文中编写的一系列文章,但它们有很多信息也适用于为web应用程序和第三方客户端服务的API。
通过使用这种方法,在短时间访问令牌失败时,客户端将需要通过发送刷新令牌来请求一个新的令牌,以便获得新的访问令牌。
这里重要的一点是,刷新令牌不应该发送到浏览器,只能发送访问令牌,因此您的第三方客户端必须非常清楚这一点,这样就不会尝试从javascript直接访问您的API,而应该将它委托给它们的后端。
API键和JWT
最后,我的Web将有一个包含所有作用域的ApiKey,而第三方ApiKeys将只有用户范围,因此我可以在上面筛选路由。无论应用程序是什么,单个真正的用户都将使用JWT令牌登录并发出请求。因此,每个请求都有一个ApiKey (基于所使用的应用程序)和一个JWT令牌(用于标识用户): ApiKey将由第三方服务器添加到报头,JWT令牌将通过用户浏览器的web_storage (检索和)添加到报头。
我不确定您是否说API键也将是JWT令牌,但如果不是,那么我也将使用JWT令牌作为API密钥,但它具有特定于每个第三方客户端的范围/角色。
走多一里路
我不反对在任何安全问题中包括我回答OWASP基金会所做的出色工作,这个案例与您最相关的是Web安全测试指南
OWASP Web安全测试指南包括用户可以在自己的组织中实现的“最佳实践”渗透测试框架,以及描述测试大多数常见web应用程序和web服务安全问题的技术的“低级别”渗透测试指南。
https://stackoverflow.com/questions/59965962
复制相似问题