例如,当我登录时,我使用有效负载{ 'userId': 1, '2fa': false}(/login路由)创建一个访问令牌,然后我执行另一条路由“/login/auth”,例如检查一次性密码是否正确,如果是,我创建了另一个jwt,但是这个2fa 设置为 true 的时间。然后后续的routes会检查2fa是否正确运行。如果没有,就会出错。这是执行此操作的正确方法还是hacky?
// middleware
const auth = (req, res, next) => {
const token = req.header('access-token');
if (!token) return res.status(401).json('Not Authorized');
try {
const payload = jwt.verify(token, 'secret1');
req.payload = payload
next();
} catch (ex) {
res.status(400).json('Invalid.');
}
};
// routes
router.post(
'/login',
async (req, res) => {
try {
/* login database stuff goes here if successful creates access token
*/
const token = jwt.sign(
{ userId, twoFactorAuthenticated: false },
'secret1',
);
res.status(200).json(token);
} catch (e) {
console.log(e);
return res.status(500).json(e);
}
},
);
router.post(
'/login/auth2',
auth,
async (req, res) => {
try {
/* verifying two factor auth logic goes here
* if succesful approves the 2fa
*/
const token = jwt.sign(
{ userId, twoFactorAuthenticated: true },
'secret1',
);
res.status(200).json(token);
} catch (e) {
console.log(e);
return res.status(500).json(e);
}
},
);
router.post(
'/some-route',
auth,
async (req, res) => {
try {
if(!req.payload.twoFactorAuthenticated)
return res.status(400).json('user has not completed second factor auth')
} catch (e) {
console.log(e);
return res.status(500).json(e);
}
},
);
Run Code Online (Sandbox Code Playgroud)
我的用例实际上并不需要登录授权,但对于不同但相同的概念适用。
您建议的流程可行,但可以改进。
\n设置 JWT 声明
\n由于 JWT 的有效负载未加密,因此它仅用于存储在验证过程中有用的非敏感信息。尽管有效负载未加密,但它已签名,并且在不知道秘密或私钥的情况下无法更改。
\n除了您自己的自定义声明之外,还有许多可能有用的标准声明twoFactorAuthenticated。您始终应该为您的令牌设置过期时间 (exp)。对于此,userId您可以使用主题声明 (sub)。
使用中间件进行路由验证
\n完成两因素身份验证后,您需要检查所有受保护路由上的 JWT。现在,您已将检查放入 \xe2\x80\x98some-route\xe2\x80\x99 控制器本身,但如果您有多个受保护的路由,最好为此定义中间件。
\n使用仅 http 的 cookie 来存储生命周期较短的 JWT
\n在您的解决方案中,您将令牌发送到客户端,并让客户端将其添加到身份验证标头中。这可能意味着令牌将存储在本地存储中。为此,使用安全的 http cookie可能更安全,其生命周期较短,例如 10 分钟左右。这意味着,如果令牌被泄露,您的 API 容易受到攻击的时间最多为 10 分钟。对于用户来说,每 10 分钟必须进行一次身份验证是一种可怕的用户体验。因此,\xe2\x80\x99 就是您可能想要实现刷新令牌的原因。
\n使用刷新令牌并且仅使用一次
\n在您的示例中,验证双因素身份验证后,您发回一个设置为 的twoFactorAuthenticated令牌true。正如之前所建议的,您可以将其发送到生命周期较短的安全 cookie 中。同时,您生成一个具有更长过期时间的刷新令牌,例如 4 小时。当cookie在10分钟后过期时,客户端可以使用刷新令牌一次来获取新的cookie和新的刷新令牌。
重要的:
\n这需要在客户端和服务器端进行一些实现,但我认为这会使您的身份验证过程更加可靠。
\n| 归档时间: |
|
| 查看次数: |
692 次 |
| 最近记录: |