golang实现jwt

发布时间:2024-07-07 16:11:35

什么是JWT?

JSON Web Token(JWT)是一种开放的标准,用于在网络应用间传输信息。它由三部分组成:头部、载荷和签名。头部通常由两部分组成:token的类型,即JWT,并且采用的哈希算法。载荷存放需要传输的信息,可以包含任意数量的公共或私有声明。签名部分通过对头部和载荷进行编码加密而获得,以确保数据的完整性。

Golang实现JWT

在Golang中,我们可以使用第三方库github.com/dgrijalva/jwt-go来实现JWT功能。首先,我们需要在项目中引入该库:

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

接下来,我们可以定义一个结构体来表示我们的Payload,即要传输的信息。比如,我们想要传输用户的ID和用户名:

type MyCustomClaims struct {
    UserID   int    `json:"user_id"`
    UserName string `json:"user_name"`
    jwt.StandardClaims
}

然后,我们可以编写一个函数来生成JWT并签名:

func GenerateJWT(userID int, userName string) (string, error) {
    claims := MyCustomClaims{
        userID,
        userName,
        jwt.StandardClaims{
            ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
            Issuer:    "my_app",
        },
    }

    token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

    jwtSecret := []byte("my_secret_key")

    signedToken, err := token.SignedString(jwtSecret)
    if err != nil {
        return "", err
    }

    return signedToken, nil
}

在上述代码中,我们通过指定SigningMethod来选择签名算法(这里选择了HS256)。我们还设置了过期时间和发布者。最后,使用密钥进行签名,生成JWT字符串。

接下来,我们可以编写一个函数来解析和验证JWT:

func ParseAndValidateJWT(tokenString string) (*MyCustomClaims, error) {
    jwtSecret := []byte("my_secret_key")

    token, err := jwt.ParseWithClaims(tokenString, &MyCustomClaims{}, func(token *jwt.Token) (interface{}, error) {
        return jwtSecret, nil
    })
    if err != nil {
        return nil, err
    }

    if !token.Valid {
        return nil, errors.New("invalid token")
    }

    claims, ok := token.Claims.(*MyCustomClaims)
    if !ok {
        return nil, errors.New("invalid token claims")
    }

    return claims, nil
}

在上述代码中,我们通过ParseWithClaims方法解析JWT并验证签名。然后,我们可以判断JWT是否有效,并将载荷转换为我们定义的结构体。

使用JWT

现在我们已经实现了生成和解析JWT的功能,我们可以使用它来保护我们的API。假设我们有一个需要验证用户身份的API接口,我们可以在请求头中添加JWT并在服务器端进行验证。以下是一个简单的示例:

func AuthMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        tokenString := r.Header.Get("Authorization")
        if tokenString == "" {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }

        tokenSlice := strings.Split(tokenString, " ")
        if len(tokenSlice) != 2 || tokenSlice[0] != "Bearer" {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }

        token := tokenSlice[1]

        claims, err := ParseAndValidateJWT(token)
        if err != nil {
            w.WriteHeader(http.StatusUnauthorized)
            return
        }

        // 验证通过,将载荷保存在请求上下文中,供后续处理程序使用
        ctx := context.WithValue(r.Context(), "user", claims)
        next.ServeHTTP(w, r.WithContext(ctx))
    })
}

在以上代码中,AuthMiddleware函数作为中间件使用,用于验证JWT。如果未提供有效的Authorization头或者JWT无效,将返回未经授权的状态码。如果JWT验证通过,我们将载荷存储在请求的上下文中,以供后续处理程序使用。

结论

通过Golang的第三方库jwt-go,我们可以轻松实现JWT功能。JWT提供了一种可靠的身份验证和授权机制,可以在跨域和分布式环境中广泛应用。通过使用JWT,我们可以简化身份验证和授权的流程,提高应用程序的安全性。

相关推荐