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



我正在使用go-swagger,BearerAuth使用JWT令牌。除了实际的令牌外,我还收到了包含用户名等数据的声明。

如何在下面的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()
})
}

首先,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.MapClaims选项进行swagger generate来减少繁琐,以便它将此类型用于声明而不是interface{}

JWT 由 3 个部分组成,按标点符号拆分 - 令牌本身是 base64 编码的。

例如,这里有一个来自 https://jwt.io/的令牌

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

您需要拆分和解码,您是在第二部分之后,其中包含只是普通 JSON 的有效负载。

所以在伪代码中,它看起来像这样;

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

您将在 https://jwt.io/中看到更具体的示例

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

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);

最新更新