JWT 子声明在验证期间被忽略
JWT sub claim gets ignored during verification
好吧,这个问题可能很天真,因为我是第一次在我的节点应用程序中实现 JWT,而且我对此有太多疑问。
首先我不清楚iss
、sub
和aud
的说法。根据我的基本理解,我知道 iss
是令牌的发行者,所以我可以假设它是应用程序的公司名称。 sub
是令牌的主题,或者简单来说可能是用户 identity/username。最后,aud
是针对听众的,或者简单来说就是 api 服务器 url/resource 服务器。如果我正确理解了这些条款,请告诉我。
现在,凭借我有限的知识,我已经设置了基本的 JWT 签名和验证。一个小片段如下:
JWT.js
module.exports = {
sign: (payload, options) => {
let signOptions = {
issuer: config.JWT_ISSUER,
subject: options.subject,
audience: config.JWT_AUDIENCE,
expiresIn: "24h",
};
return jwt.sign(payload, config.JWT_SECRET, signOptions);
},
verify: (token, options) => {
let verifyOptions = {
issuer: config.JWT_ISSUER,
subject: options.subject,
audience: config.JWT_AUDIENCE,
expiresIn: "24h",
};
try {
return jwt.verify(token, config.JWT_SECRET, verifyOptions);
}
catch (err){
return false;
}
},
现发行代币如下:
// Issue JWT token
let userData = {
user_name: user.userName,
client_id: user.clientId
};
const token = jwt.sign({ userData }, { subject: user.userName });
验证如下:
// Verify the token
const authData = jwt.verify(token, { subject: req.body.subject });
主要问题
当我向 api 端点发送请求进行验证时,如果我发送请求时正文中没有主题字段(,则令牌会带有子字段),令牌验证成功。但是,如果我在正文中发送带有 correct/incorrect 值的主题字段,它会分别得到 success/forbidden。
- 为什么会这样?
- 为什么在请求中没有传递子字段时令牌不被禁止?
- 需要手动验证吗?
根据JWT standard,
4.1.2. "sub" (Subject) Claim
“子”(主题)声明标识主体是
JWT 的主题。 JWT 中的声明通常是声明
关于这个主题。主题值必须是
在发行人的上下文中是本地唯一的,或者是全局唯一的。
此索赔的处理通常是特定于应用程序的。这
“sub”值是包含 StringOrURI 的区分大小写的字符串
价值。使用此声明是可选的。
因此,当您没有它时,它会通过,但不正确的值会导致失败。 jwt
包遵循标准。
现在,如果您打算强制执行,则必须将其自定义,但请注意,您可能无法使用不认为强制执行的第 3 方身份验证(如果这是您的用例)。 (不知道现实生活中是否真的如此)
好吧,这个问题可能很天真,因为我是第一次在我的节点应用程序中实现 JWT,而且我对此有太多疑问。
首先我不清楚iss
、sub
和aud
的说法。根据我的基本理解,我知道 iss
是令牌的发行者,所以我可以假设它是应用程序的公司名称。 sub
是令牌的主题,或者简单来说可能是用户 identity/username。最后,aud
是针对听众的,或者简单来说就是 api 服务器 url/resource 服务器。如果我正确理解了这些条款,请告诉我。
现在,凭借我有限的知识,我已经设置了基本的 JWT 签名和验证。一个小片段如下:
JWT.js
module.exports = {
sign: (payload, options) => {
let signOptions = {
issuer: config.JWT_ISSUER,
subject: options.subject,
audience: config.JWT_AUDIENCE,
expiresIn: "24h",
};
return jwt.sign(payload, config.JWT_SECRET, signOptions);
},
verify: (token, options) => {
let verifyOptions = {
issuer: config.JWT_ISSUER,
subject: options.subject,
audience: config.JWT_AUDIENCE,
expiresIn: "24h",
};
try {
return jwt.verify(token, config.JWT_SECRET, verifyOptions);
}
catch (err){
return false;
}
},
现发行代币如下:
// Issue JWT token
let userData = {
user_name: user.userName,
client_id: user.clientId
};
const token = jwt.sign({ userData }, { subject: user.userName });
验证如下:
// Verify the token
const authData = jwt.verify(token, { subject: req.body.subject });
主要问题
当我向 api 端点发送请求进行验证时,如果我发送请求时正文中没有主题字段(,则令牌会带有子字段),令牌验证成功。但是,如果我在正文中发送带有 correct/incorrect 值的主题字段,它会分别得到 success/forbidden。
- 为什么会这样?
- 为什么在请求中没有传递子字段时令牌不被禁止?
- 需要手动验证吗?
根据JWT standard,
4.1.2. "sub" (Subject) Claim
“子”(主题)声明标识主体是 JWT 的主题。 JWT 中的声明通常是声明 关于这个主题。主题值必须是 在发行人的上下文中是本地唯一的,或者是全局唯一的。 此索赔的处理通常是特定于应用程序的。这 “sub”值是包含 StringOrURI 的区分大小写的字符串 价值。使用此声明是可选的。
因此,当您没有它时,它会通过,但不正确的值会导致失败。 jwt
包遵循标准。
现在,如果您打算强制执行,则必须将其自定义,但请注意,您可能无法使用不认为强制执行的第 3 方身份验证(如果这是您的用例)。 (不知道现实生活中是否真的如此)