这是我参与「第五届青训营 」伴学笔记创作活动的第7天
jwt(JSON Web Token), 是一种跨域解决认证的方案
目前主流认证方式主要有session, cookie等, 在单机情况下性能不错, 但是在集群或者跨域情况, 就需要保证每台机器都能够读取session.
而jwt相当于把session认证这个过程交给前端, 用以解决以上问题.
JWT原理
jwt主要是用来发放token, server通过一定的密钥和一定的加密方式, 来对需要携带的信息生成json对象, 并对其进行加密
token中主要携带一些用户的认证信息, 如id, name等, 并且, jwt会为token设置一个过期时间, 服务器在jwt过程中的主要作用之一, 就是解析token的过期时间, 来判断token是否过期.
JWT-GO的简单使用
首先导入"github.com/dgrijalva/jwt-go"包, 然后定义一个包含我们想要让token携带的信息的数据结构, 如下所示, 我们希望token携带UserId和UserName两个字段.
import "github.com/dgrijalva/jwt-go"
type MyClaims struct {
UserId uint `json:"user_id"`
UserName string `json:"username"`
jwt.StandardClaims
}
其次是jwt.StandardClaims, 这是jwt提供的一个标准结构体, 包含一些默认信息, 和gorm的gorm.Model很像
// Structured version of Claims Section, as referenced at
// https://tools.ietf.org/html/rfc7519#section-4.1
// See examples for how to use this with your own claim types
type StandardClaims struct {
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"`
}
我们主要用到的, 是ExpiresAt过期时间戳, IssuedAt当前时间戳, Issuer签名这几个
发放token
func CreateToken(userId uint, userName string) (string, error) {
expireTime := time.Now().Add(time.Duration(config.TokenLiveTime) * time.Hour) //过期时间
nowTime := time.Now() //当前时间
claims := MyClaims{
UserId: userId,
UserName: userName,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expireTime.Unix(), //过期时间戳
IssuedAt: nowTime.Unix(), //当前时间戳
Issuer: "byteDance", //颁发者签名
Subject: "userToken", //签名主题
},
}
//token加密
tokenStruct := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
//颁发token
return tokenStruct.SignedString([]byte(config.Key))
}
一般, 我们需要对我们的token进行加密, jwt提供了几种加密方式, 这里使用最简单的HS256机密
注意, 生成token时, 应当传入[]byte类型的数据, 否则会提示Key is Vaild