在Go中使用JWT | 青训营

117 阅读3分钟

一、介绍

在当今的互联网时代,安全认证和授权已成为任何Web应用程序不可或缺的一部分。JSON Web Tokens(JWT)是一种开放标准,用于在双方之间安全地传输信息。在本文中,我们将探讨在Go语言中如何使用JWT,通过实际示例来展示其理论和实践。

二、JWT的结构和原理

JWT由三部分组成,分别是头部(Header)、负载(Payload)和签名(Signature)。

  1. 头部:包含一个声明,描述了JWT使用的算法和签发者。它被压缩并base64编码,放在JWT的开头。
  2. 负载:包含实际传输的数据,如用户信息、角色权限等。这些信息被base64编码后,放在头部之后、签名之前。
  3. 签名:通过对头部和负载使用一个密钥进行签名,确保数据的完整性和真实性。

JWT的头部是一个JSON对象,包含两个字段:alg(算法)和typ(类型)。其中,alg字段指定了签名算法,typ字段描述了JWT的类型。

JWT的负载也是一个JSON对象,可以包含自定义的声明。这些声明可以是任意的键值对,用于传递信息。

三、在Go语言中使用JWT

在Go语言中使用JWT,我们可以借助第三方库来简化操作。其中最流行的库是jwt-go

首先,我们需要安装该库。打开终端,进入项目的目录,然后运行以下命令:

go get -u github.com/dgrijalva/jwt-go

接下来,我们将通过一个示例来展示如何生成和验证JWT。

  1. 生成JWT

    //定义一个加密key
    var Key = []byte("JWT")
    //接着创建一个名为MyClaims结构体实现Claims接口
    type MyClaims struct {
        UserName string `json:"username"`
        jwt.StandardClaims
    }
    //创建token的方法
    func CreateToken() (string, error) {
        c := MyClaims{
           UserName: "GGBond",
           StandardClaims: jwt.StandardClaims{
              NotBefore: time.Now().Unix(),                     //生效时间戳
              ExpiresAt: time.Now().Add(24 * time.Hour).Unix(), //过期时间时间戳
              Issuer:    "zhoumo",                              //签发人
           },
        }
        token := jwt.NewWithClaims(jwt.SigningMethodHS256, c) //传入签名方式和MyClaims的实例化,返回一个token
        s, e := token.SignedString(Key)                       //传入加密key,返回string类型的加密字符串
        return s, e                                           // 返回加密串
    }
    
  2. 验证JWT

    示例代码如下:

    func CheckToken(token string) (*MyClaims, bool) {
        //按照官方文档写
        t, _ := jwt.ParseWithClaims(token, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
           return Key, nil
        })
        //验证是否正确,正确返回加密串,true
        if key, _ := t.Claims.(*MyClaims); t.Valid {
           return key, true
        } else {
           return nil, false
        }
    }
    

1.在main()方法中进行验证

    func main() {
        s, e := CreateToken()
        if e != nil {
           fmt.Printf("%s", e)
        }
        fmt.Println(s)             //打印加密串
        token, ok := CheckToken(s) //传入加密串进行验证
        fmt.Println(ok)
        fmt.Println(token.UserName) //输出用户
    }

可以看到输出的UserName和我们事先定义好的一致 image.png 四、总结和最佳实践

通过上述示例,我们可以看到在Go语言中使用JWT的基本步骤。然而,实际使用中还需要考虑一些额外的问题和最佳实践。以下是一些建议:

  1. 在生成Token时,确保对敏感信息进行加密或哈希处理,以保护用户数据的安全性。不要将敏感信息存储在Token的负载中。
  2. 在验证Token时,除了检查签名的正确性外,还应检查Token的有效期。过期的Token应被视为无效。