如何使我的代码生成令牌并将其返回以对用户进行身份验证?

Posted

技术标签:

【中文标题】如何使我的代码生成令牌并将其返回以对用户进行身份验证?【英文标题】:How can I make my code to generate token and return it to authenticate a user? 【发布时间】:2020-05-20 03:35:03 【问题描述】:

我有以下用于生成令牌的代码。我关注这个tutorial。当我使用 postman 使用注册的用户名和密码测试代码时,它返回了JsonWebTokenError: jwt malform。经过仔细审查,我发现错误来自jwt.verify 部分。

    我需要进行哪些调整才能生成令牌? 如何配置它,以便当用户发出登录请求时,假设他传递了他的用户名和密码以及电子邮件和密码,客户端必须传递一个客户端身份 ( [payload + clientID] ),用于服务器知道要为谁签署令牌。 我需要传入Postman Header 来测试令牌系统的工作情况吗?

代码已编辑

const jwt = require('jsonwebtoken');
const fs = require('fs');

// PRIVATE and PUBLIC key
const publicKey = fs.readFileSync(__dirname + '/public.key', 'utf8');
const privateKey = fs.readFileSync(__dirname + '/private.key', 'utf8');

// Returns secret only known to server at runtime
exports.getSecret = () => 
  const secret = require('../config/secret.json').secret;
  return secret;
;

// Returns token
exports.getToken = (payload, signOptions) => 
  if (!signOptions) 
    signOptions = 
      issuer:  "Myself",
      expiresIn:  "30d", 
      algorithm:  "RS256"
        
  ;
   const token = jwt.sign(payload, privateKey, options);
  return (token);
;

// Returns result of token validation
exports.validateToken = (token, verifyOptions) => 

  if (!verifyOptions) 
    verifyOptions = 
      issuer:  "Myself",
      expiresIn:  "30d", 
      algorithm:  "RS256"
        
  ;
  try 
    return jwt.verify(token, publicKey, verifyOptions);
   catch (err) 
    return err;
  
;

// Returns validation result of token
exports.token_post = (req, res) => 
  res.send(this.validateToken(req.header.Authorization, this.getSecret()));
;

exports.hasPermission = (token, resource) => 
  const result = this.validateToken(token, this.getSecret());
  console.log(result);
  if (result.name === 'JsonWebTokenError') 
    return false;
   else if (result.permissions) 
    let permissionSet = new Set(result.permissions);
    console.log('permissions in token', JSON.stringify(permissionSet));
    return permissionSet.has(resource);
   else 
    return false;
  
;

【问题讨论】:

【参考方案1】:

您没有向this.validateToken 提供好的论据。

你应该给它verifyOptions而不是this.getSecret()

顺便说一句,这不是秘密,而是公钥,所以我不建议使用此名称。而且您正在读取两次公钥。

您的hasPermission 函数应如下所示:

exports.hasPermission = (token, resource, $Options) => 
    const result = this.validateToken(token, $Options);
    console.log(result);
    if (result.name === 'JsonWebTokenError') 
        return false;
     else if (result.permissions) 
        let permissionSet = new Set(result.permissions);
        console.log('permissions in token', JSON.stringify(permissionSet));
        return permissionSet.has(resource);
     else 
        return false;
    
;

不要忘记更改调用该函数的代码。 $Options 是您用来签署令牌的那个,在教程中是 signOptions

【讨论】:

谢谢@Waelmio。让我尝试调整我的代码。顺便说一句,你建议我在哪里使用公钥? 我测试了它,它对我有用。我将通过编辑我的答案来发布代码。 我看到你改变了你的代码,但这里getSecret 的返回值是多少?如果不是signOptions,它仍然无法工作。您必须提供这些选项来验证令牌。 @JetroOlowole “你建议我在哪里使用公钥”是什么意思? ? 感谢 Waelmio。这么晚才看到。让我先试试这个解决方案。

以上是关于如何使我的代码生成令牌并将其返回以对用户进行身份验证?的主要内容,如果未能解决你的问题,请参考以下文章

为 api 访问生成安全令牌

如何使我的身份验证令牌不会过期?

将 Windows 用户“令牌”传递给 WCF 进行身份验证

从 Angular 访问受 Google IAP 保护的 API

如何使用标头中的用户 JWT 令牌转发授权并将其与 cookie 中的 JWT 令牌进行比较以验证用户?

如何使 IdentityServer 将用户身份添加到访问令牌?