我正在学习围棋,我想用Auth0设置一个简单的应用程序. 通过使用their个教程,我能够为我的API端点设置基本身份验证. 现在,我想使用JWT令牌添加权限处理. 因此,我为API-Endpoint激活了RBAC并添加了权限. 我将教程中的流程用于定制声明,但用它编写了自己的中间件,并对其进行了调整以与杜松子wine 一起工作.

func NeedsPermission(expectedScope string) gin.HandlerFunc {
    return func(context *gin.Context) {
        token := context.Request.Context().Value(jwtmiddleware.ContextKey{}).(*validator.ValidatedClaims)

        claims := token.CustomClaims.(*CustomClaims)

        if !claims.HasScope(expectedScope) {
            context.AbortWithStatus(403)
        }
        context.Next()
    }
}

问题是,令牌中没有自定义声明,只有默认的:OpenID、个人资料和邮箱声明.

以下是令牌内容:

{
  "iss": "https://dev-****.us.auth0.com/",
  "sub": "google-oauth2|****",
  "aud": [
    "localhost:3000/books",
    "https://dev-****.us.auth0.com/userinfo"
  ],
  "iat": 1701789297,
  "exp": 1701875697,
  "azp": "***",
  "scope": "openid profile email",
  "permissions": [
    "read:books"
  ]
}

所以它确实有一个字段权限,但是我如何使用auth 0/go-jwt-middleware访问它,或者我必须先以某种方式解码它?

推荐答案

权限是一个自定义声明,因此您需要传递WithCustomClaims选项并实现validator.CustomClaims接口. 然后,当您创建验证器时:

    ...
    jwtValidator, _ := validator.New(
        keyFunc,
        validator.HS256,
        issuer,
        audience,
        validator.WithCustomClaims(func() validator.CustomClaims {
            return &MyClaims{}
        }),
    )
    mw := jwtmiddleware.New(jwtValidator.ValidateToken)
    ...

MyClaims是这样的.注意你的HasScope方法:

type MyClaims struct {
    Permissions    []string `json:"permissions"`
}

func (c *MyClaims) Validate(ctx context.Context) error {
    // Validate structure of permissions here, i.e. check for 400 not 403
    return nil
}

func (c MyClaims) HasScope(requiredPerm string) bool {
    for _, perm := range c.Permissions {
        if perm == requiredPerm {
            return true
        }
    }
    return false
}

Go相关问答推荐

语法-for循环中的initit陈述是否允许分配?

Golang html/模板&需要错误数量的参数1在模板中使用';调用';获得0&q;

将类型定义为泛型类型实例化

转到http服务器头内容-类型设置为多部分/表单-数据,但在客户端获取内容-类型:文本/纯文本

埃拉托塞尼筛:加快交叉关闭倍数步骤

golang regex基于关键字拆分字符串

我怎样才能改进这个嵌套逻辑以使其正常工作并提高性能

golang testscript .txtar 语法,用于 stderr 或 stdout 中包含的文本

未实现的 desc = 未知服务 pb.AuthService 我的简单身份验证服务器上出现错误

从Go中的随机日期开始以天为单位获取时间

assert: mock: I don't know what to return because the method call was unexpected 在 Go 中编写单元测试时出错

访问传递给可变参数函数的通用 struct 的特定字段

查找、解析和验证邮箱地址

为什么当我忽略 template.New() 程序可以成功运行?

Gorm 在保存/创建时序列化 struct

合并几千万文件最快的方法是什么

如何从字符串中删除多个换行符`\n`但只保留一个?

退格字符在围棋操场中不起作用

AWS EKS 上的 Golang REST API 部署因 CrashLoopBackOff 而失败

如何发送带有登录数据的 GET 请求并将 cookie 数据保存到 txt 文件?