golang JWT 包生成 Token, 验证 Token

本贴最后更新于 2200 天前,其中的信息可能已经时移世异

简介

  • json web token 简称 jwt 是一种轻量级的 规范
  • 常用与用户认证
  • 大致由 3 部分构成:
  • Header (头部)
  • Payload (载荷)
  • Signature (签名)
  • . 拼接
  • Token = Header + '.' + Payload + '.' + Signature

用来表明签名的加密算法 token 类型等.

{
    "typ": "JWT",
    "alg": "HS256"lag
}

以上 json 转为 base64 生成 header

Payload

Payload 记录你需要的信息. 其中应该包含 Claims

Claims

Audience string `json:"aud,omitempty"`  
ExpiresAt int64 `json:"exp,omitempty"`  
Id string `json:"jti,omitempty"` 
IssuedAt int64 `json:"iat,omitempty"`  
Issuer string `json:"iss,omitempty"`  
NotBefore int64 `json:"nbf,omitempty"`  
Subject string `json:"sub,omitempty"`
1. aud 标识token的接收者.
2. exp 过期时间.通常与Unix UTC时间做对比过期后token无效
3. jti 是自定义的id号 
4. iat 签名发行时间.
5. iss 是签名的发行者.
6. nbf 这条token信息生效时间.这个值可以不设置,但是设定后,一定要大于当前Unix UTC,否则token将会延迟生效.
7. sub 签名面向的用户

Signature

通过 header 生明的加密方法生成 签名.

JWT 包下载

go get github.com/dgrijalva/jwt-go

简单使用

生成 Token

Payload 结构体

type jwtCustomClaims struct {
	jwt.StandardClaims

	// 追加自己需要的信息
	Uid   uint `json:"uid"`
	Admin bool `json:"admin"`
}

编写生成 token 的函数

/**
 * 生成 token
 * SecretKey 是一个 const 常量
 */
func CreateToken(SecretKey []byte, issuer string, Uid uint, isAdmin bool) (tokenString string, err error) {
	claims := &jwtCustomClaims{
		jwt.StandardClaims{
			ExpiresAt: int64(time.Now().Add(time.Hour * 72).Unix()),
			Issuer:    issuer,
		},
		Uid,
		isAdmin,
	}
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err = token.SignedString(SecretKey)
	return
}

test 一下

func TestCreateToken(t *testing.T)  {  
   token, _ := CreateToken([]byte(SecretKey), "YDQ", 2222, true)  
   fmt.Println(token)
}

结果是这样的.

=== RUN   TestCreateToken

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDA2MDc2MzYsImlzcyI6IllEUSIsInVpZCI6MjIyMiwiYWRtaW4iOnRydWV9.oaX63ScaDttkhC31bgjvPSr4PjvBb55UanAA_QP5zpc
--- PASS: TestCreateToken (0.00s)
PASS

解析 Token

解析函数

/**
 * 解析 token
 */
func ParseToken(tokenSrt string, SecretKey []byte) (claims jwt.Claims, err error) {
	var token *jwt.Token
	token, err = jwt.Parse(tokenSrt, func(*jwt.Token) (interface{}, error) {
		return SecretKey, nil
	})
	claims = token.Claims
	return
}

合并到一直测试.

func TestCreateToken(t *testing.T) {
	token, _ := CreateToken([]byte(SecretKey), "YDQ", 2222, true)
	fmt.Println(token)

	claims, err := ParseToken(token, []byte(SecretKey))
	if nil != err {
		fmt.Println(" err :", err)
	}
	fmt.Println("claims:", claims)
	fmt.Println("claims uid:", claims.(jwt.MapClaims)["uid"])
}

结果是这样的.

=== RUN   TestCreateToken

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1NDA2MDgyODgsImlzcyI6IllEUSIsInVpZCI6MjIyMiwiYWRtaW4iOnRydWV9.8wE-_Wx-DHI2GMXJ9KT5JOndst2CCEaUNEIGDy9CUbM
claims: map[exp:1.540608288e+09 iss:YDQ uid:2222 admin:true]
claims uid: 2222
--- PASS: TestCreateToken (0.00s)
PASS

这里要注意, 信息 parse 后与签名信息不一致, 会报 err: signature is invalid

END

2018/10/24
祝各位程序猿 1024 节日快乐.~ 😋

  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    497 引用 • 1387 回帖 • 283 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 2 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...
  • shockerli 1

    go get github.com/jwt-go

    包地址不对吧?

    1 回复
  • K
    作者

    已经更正.~ 感谢提醒