如何从API处理程序函数中访问JWT声明?

时间:2018-08-29 19:42:05

标签: jwt swagger openapi go-swagger

我正在使用JWT令牌对BearerAuth进行调整。除了实际的令牌外,我还将收到包含用户名等数据的声明。

如何在下面的api.ItemsCreateItemHandler函数中访问声明?

package restapi

func configureAPI(api *operations.MyAPI) http.Handler {
    api.BearerAuth = func(token string) (interface{}, error) {
        jwtToken := strings.Replace(token, "Bearer ", "", -1)
        // skipped token verification

        claims, _ := parsedToken.Claims.(jwt.MapClaims)
  }

  api.ItemsCreateItemHandler = items.CreateItemHandlerFunc(func(params items.CreateItemParams, principal interface{}) middleware.Responder {
    // FIXME: Here I need to be able to access JWT claims
    if err := createItem(params.Body, claims); err != nil {
            return nil // handle error
        }
        return items.NewCreateItemCreated()
    })
}

3 个答案:

答案 0 :(得分:0)

JWT由三部分组成,按标点进行拆分-令牌本身是base64编码的。

例如,来自https://jwt.io/

的令牌
  。

您将要拆分和解码,紧随第二部分之后,其中包含仅是纯JSON的有效载荷。

因此在伪代码中,它看起来像;

json = Base64Decode(split(".", yourData)[1])

您将在https://jwt.io/

上看到更具体的示例

答案 1 :(得分:0)

我有一个存储令牌并包含解析方法的类:

import io.jsonwebtoken.*;

 @AllArgsConstructor
public class RawAccessJwtToken implements JwtToken {

    private String token;

    @Override
    public String getToken() {
        return token;
    }

    public Jws<Claims> parseClaims(String signingKey) {
        try {
            return Jwts.parser().setSigningKey(signingKey).parseClaimsJws(this.token);
        } catch (UnsupportedJwtException | MalformedJwtException | IllegalArgumentException e) {
            throw  new BadCredentialsException("Invalid JWT token: " + e);
        } catch (ExpiredJwtException expiredException){
            throw new JwtExpiredTokenException(this, "JWT Token expired", expiredException);
        }
    }
}

使用该类,我可以提取用户角色:

 Jws<Claims> claimsJws = token.parseClaims(signingKey);

        List<String> scopes = claimsJws.getBody().get("scopes",
                 List.class);

答案 2 :(得分:0)

首先,您的 BearerAuth 实现旨在返回安全主体(在这种情况下可以是您的声明),此值随后将在 principal 参数中传递给您的处理程序。

所以这样做的方法是:

package restapi

import (
    jwt "github.com/dgrijalva/jwt-go"
    // ...
)

func configureAPI(api *operations.MyAPI) http.Handler {
    api.BearerAuth = func(token string) (interface{}, error) {
        jwtToken := strings.Replace(token, "Bearer ", "", -1)
        // skipped token verification
        claims, _ := parsedToken.Claims.(jwt.MapClaims)
        return claims, nil
    }

    api.ItemsCreateItemHandler = items.CreateItemHandlerFunc(func(params items.CreateItemParams, principal interface{}) middleware.Responder {
        claims, ok := principal.(jwt.MapClaims)
        if !ok {
            // handle error
        }
        if err := createItem(params.Body, claims); err != nil {
            return nil // handle error
        }
        return items.NewCreateItemCreated()
    })
}

您可以通过使用 --principal jwt.MapClaimsswagger generate 选项来减少这种麻烦,以便它使用这种类型的声明而不是 interface{}