在 Java 中生成 JWT 令牌以进行 hasura 授权

Posted

技术标签:

【中文标题】在 Java 中生成 JWT 令牌以进行 hasura 授权【英文标题】:Generate JWT Token In Java for hasura authorization 【发布时间】:2021-04-11 06:14:23 【问题描述】:

我们使用 spring boot 作为后端仅用于身份验证,并在 hasura 中处理生成 jwt 令牌。

我在正确生成 JWT 时遇到问题。

public String generateToken(String email,String role,Long id)  
        Map<String, Object> claims = new HashMap<>();

        Map<String,Object> claim =new HashMap<>();
        claims.put("x-hasura-user-id",id);
        claims.put("x-hasura-default-role",role);
        claims.put("x-hasura-allowed-roles", new String[]"job_seeker", "employer", "admin");

        claim.put("https://hasura.io/jwt/claims",claims);
        System.out.println(claim);
        return doGenerateToken(claim, email);
    

    private String doGenerateToken(Map<String, Object> claim, String subject) 
        return Jwts.builder().setClaims(claim).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + Long.parseLong(tokenValidity))).signWith(SignatureAlgorithm.HS256, secret).compact();
    

这是生成 jwt 令牌为

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJyb3NhbjEyM0BnbWFpbC5jb20iLCJodHRwczovL2hhc3VyYS5pby9qd3QvY2xhaW1zIjp7IngtaGFzdXJhLWRlZmF1bHQtcm9sZSI6ImFkbWluIiwieC1oYXN1cmEtdXNlci1pZCI6NCwieC1oYXN1cmEtYWxsb3dlZC1yb2xlcyI6WyJqb2Jfc2Vla2VyIiwiZW1wbG95ZXIiLCJhZG1pbiJdfSwiZXhwIjoxNjA5ODU1OTA2LCJpYXQiOjE2MDk4NTExMDZ9.WqJE1xLIsycW92tzFXdq0UHub3qUfQbUvUax9rvks4Q

但它 hasura 正在返回无效签名。在节点中的位置

 generateToken: (user: any) => 
    const payload = 
      sub: user.email,
      "https://hasura.io/jwt/claims": 
        "x-hasura-default-role": `$user.role.name`,
        "x-hasura-user-id": `$user.id`,
        "x-hasura-allowed-roles": ["job_seeker", "employer", "admin"],
      ,
    ;
    return jwt.sign(payload, secretkey);
  ,

来自节点的jwt

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJib2hhcmFuaXNjaGFsQGdtYWlsLmNvbSIsImh0dHBzOi8vaGFzdXJhLmlvL2p3dC9jbGFpbXMiOnsieC1oYXN1cmEtZGVmYXVsdC1yb2xlIjoiam9iX3NlZWtlciIsIngtaGFzdXJhLXVzZXItaWQiOiIyNCIsIngtaGFzdXJhLWFsbG93ZWQtcm9sZXMiOlsiam9iX3NlZWtlciIsImVtcGxveWVyIiwiYWRtaW4iXX0sImlhdCI6MTYwOTg1NDEzMX0.8UDrqvRujakGsEtGEAu1XWl5RsFda8HaA_-97vwY62I

使用相同的密钥和算法工作得非常好。对于节点,我使用了 jsonwebtoken 库。

【问题讨论】:

【参考方案1】:

我找到了解决方案。字符串应转换为 byte[]:

 private String doGenerateToken(Map<String,Object> header,Map<String, Object> claim, String subject) 
        return Jwts.builder().setHeader(header).setClaims(claim).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiration(new Date(System.currentTimeMillis() + Long.parseLong(tokenValidity))).signWith(SignatureAlgorithm.HS256, secret.getBytes(StandardCharsets.UTF_8)).compact();
    

【讨论】:

以上是关于在 Java 中生成 JWT 令牌以进行 hasura 授权的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Laravel 5.7 中生成 JWT 刷新令牌

使用 JWT 在 c# 中生成令牌的无效签名

如何在 python 中生成唯一的身份验证令牌?

在 node.js 中生成的 JWT(JSON Web Token) 未在 java 中验证

如何根据需求在python中生成JWT

在 Java 中生成 SAS 令牌以下载 Azure 数据存储容器中的文件