JWT 全称 JSON Web Token,是目前比较流行的另一种跨域身份验证解决方案。也是被很 多人用坏的一种安全验证机制。

Golang中使用JWT 实现接口的安全验证

1、生成 Jwt Token

1、首先需要自定义一个结构体,这个结构体需要继承 jwt.StandardClaims 结构体,这个结 构体也可以自定义结构体属性,自定义的属性用于 Jwt 传值。

import (
	"github.com/dgrijalva/jwt-go"
	"time"
)
type Token struct {
	Uid int
	jwt.StandardClaims
}

2、定义生成结构体的私钥 key 以及过期时间

//义生成结构体的私钥 key
var jwtKey = []byte("123456")
//Token 过期时间
var expireTime = time.Now().Add(24 * time.Hour).Unix()

3、实例化自定义的结构体,创建 token


/**
创建token
传入用户id 方便token验证时,可直接获取
*/
func CreateToken(uid int) string {
	jwtObj := Token{uid, // 生成 token 的时候传值
		jwt.StandardClaims{
			ExpiresAt: expireTime, //过期时间
			Issuer:    "joeKai",   // 签发人
		}}
	// 使用指定的签名方法创建签名对象
	tokenObj := jwt.NewWithClaims(jwt.SigningMethodHS256, jwtObj)
	// 使用指定的 secret 签名并获得完整的编码后的字符串 token
	tokenStr, _ := tokenObj.SignedString(jwtKey)
	return tokenStr
}

2、验证 Jwt Token

1、定义方法验证 token

//验证token
func ParseToken(tokenString string) (*jwt.Token, *Token, error) {
	//创建Token实例
	token := &Token{}
	//验证Token
	jwtToken, err := jwt.ParseWithClaims(tokenString, token,
		func(token *jwt.Token) (i interface{}, err error) {
			return jwtKey, nil
		})
	return jwtToken, token, err
}

2、通过token获取用户数据


//获取用户id
func GetUserId(ctx *context.Context) (int, error) {
	tokenStr := ctx.Request.Header.Get("token")
	if tokenStr == "" {
		return 0, common.NotLoginErr()
	} else {
		token, claims, err := ParseToken(tokenStr)
		if err != nil || !token.Valid {
			fmt.Println("权限不足")
			return 0, common.NotLoginErr()
		} else {
			fmt.Println("验证通过")
			return claims.Uid, nil
		}
	}
}

关于 Jwt 的一些问题

1、JWT 不仅可以用于认证,也可以用于交换信息。有效使用 JWT,可以降低服务器查询 数据库的次数。
2、JWT 的最大缺点是,由于服务器不保存 session 状态,因此无法在使用过程中废止某 个 token,或者更改 token 的权限。也就是说,一旦 JWT 签发了,在到期之前就会始终有 效,除非服务器部署额外的逻辑。
3、JWT 本身包含了认证信息,一旦泄露,任何人都可以获得该令牌的所有权限。为了减 少盗用,JWT 的有效期应该设置得比较短。对于一些比较重要的权限,使用时应该再次对 用户进行认证。
4、为了减少盗用,JWT 不应该使用 HTTP 协议明码传输,要使用 HTTPS 协议传输。