为了账号安全,请及时绑定邮箱和手机立即绑定

验证 Auth0 ID 令牌 - 我需要使用哪个秘密

验证 Auth0 ID 令牌 - 我需要使用哪个秘密

Go
收到一只叮咚 2022-12-19 21:37:26
我正在使用 Auth0 为用户生成 JWT ID 令牌。现在我想在我的后台验证这个 ID Token。我只想从这个密钥中提取用户的身份,并检查它是否是由我的应用程序在 Auth0 中创建的。我正在使用带有jwtauth中间件的chi路由器。这是jwx的轻量级包装器。文档说我应该执行以下操作:    tokenAuth = jwtauth.New("RS256", []byte("secret"), nil)我已经尝试了几种“秘密”,例如我的 Auth0 应用程序的客户端秘密或签名证书。但它们似乎都不起作用。我仔细检查了我是否使用了正确的签名算法。它总是导致token is unauthorized.    r.Route("/users", func(r chi.Router) {        r.Use(jwtauth.Verifier(tokenAuth))        //r.Use(jwtauth.Authenticator)        r.Post("/info", usersService.InfoHandler)    })在处理程序中,我尝试获取令牌:    token, _, err := jwtauth.FromContext(r.Context())    fmt.Println("token", token)    fmt.Println("error", err)
查看完整描述

1 回答

?
慕姐8265434

TA贡献1813条经验 获得超2个赞

我现在创建了一个中间件来执行此操作。它非常简单明了,我认为没有必要使用 jwtauth 中间件。

最好的办法似乎是使用JSON Web Key Set (JWKS)。它包含验证 JWT 的所有信息。

package auth0


import (

    "context"

    "fmt"

    "github.com/lestrrat-go/jwx/jwk"

    "github.com/lestrrat-go/jwx/jwt"

    log "github.com/sirupsen/logrus"

    "net/http"

)


var (

    ErrInvalidToken = fmt.Errorf("invalid token")

    ErrNoToken      = fmt.Errorf("no token found")

)


type middleware struct {

    keySet   jwk.Set

    audience string

    issuer   string

}


type AuthUser struct {

    ID    string `json:"id"`

    Email string `json:"email"`

}


type userKeyType string


const userKey = userKeyType("user")


type Middleware interface {

    AuthenticateUser(next http.Handler) http.Handler

}


var _ Middleware = &middleware{}


func NewMiddleware(issuer string, audience string) (middleware, error) {

    // TODO implement auto rotation/refresh

    keySet, err := jwk.Fetch(context.Background(), fmt.Sprintf("%s.well-known/jwks.json", issuer))

    if err != nil {

        return middleware{}, err

    }


    return middleware{

        keySet:   keySet,

        audience: audience,

        issuer:   issuer,

    }, nil


}


func (m *middleware) AuthenticateUser(next http.Handler) http.Handler {

    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {


        authHeader := r.Header.Get("Authorization")

        if authHeader == "" {

            log.Debug("no authorization header found")

            http.Error(w, ErrNoToken.Error(), http.StatusForbidden)

            return

        }

        bearerToken := authHeader[7:]

        if bearerToken == "" {

            log.Error("no bearer token found")

            http.Error(w, ErrNoToken.Error(), http.StatusForbidden)

            return

        }


        token, err := jwt.Parse([]byte(bearerToken), jwt.WithKeySet(m.keySet))

        if err != nil {

            log.Error("error parsing token")

            http.Error(w, ErrInvalidToken.Error(), http.StatusForbidden)

            return

        }


        if err := jwt.Validate(token,

            jwt.WithAudience(m.audience),

            jwt.WithIssuer(m.issuer)); err != nil {

            log.Error("error validating token")

            http.Error(w, ErrInvalidToken.Error(), http.StatusForbidden)

            return

        }


        emailValue, ok := token.Get("email")

        if !ok {

            log.Error("error no email found")

            http.Error(w, ErrInvalidToken.Error(), http.StatusForbidden)

            return

        }


        email, ok := emailValue.(string)

        if !ok {

            log.Error("error email not a string")

            http.Error(w, ErrInvalidToken.Error(), http.StatusForbidden)

            return

        }


        if token.Subject() == "" && email == "" {

            log.Error("error no subject or email found")

            http.Error(w, ErrInvalidToken.Error(), http.StatusForbidden)

            return

        }


        ctx := context.WithValue(r.Context(), userKey, AuthUser{

            ID:    token.Subject(),

            Email: email,

        })


        next.ServeHTTP(w, r.WithContext(ctx))

    })

}


func GetUserFromContext(ctx context.Context) (AuthUser, error) {

    user, ok := ctx.Value(userKey).(AuthUser)

    if !ok {

        return AuthUser{}, fmt.Errorf("could not get user from context")

    }

    return user, nil

}


查看完整回答
反对 回复 2022-12-19
  • 1 回答
  • 0 关注
  • 88 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信