go使用JWT进行跨域认证最全教学
JWT前言
JWT是JSON Web Token的缩写。JWT本身没有定义任何技术实现,它只是定义了一种基于Token的会话管理的规则,涵盖Token需要包含的标准内容和Token的生成过程。
JWT组成
JWT由.分割的三部分组成,这三部分依次是:
- 头部(Header)
作用:记录令牌类型、签名算法等 例如: - 负载(Payload)
作用:携带一些用户信息 例如 - 签名(Signature)
作用:防止Token被篡改、确保安全性 例如 计算出来的签名,一个字符串
头部和负载以json形式存在,这就是JWT中的JSON,三部分的内容都分别单独经过了Base64编码,以.拼接成一个JWT Token。
JWT在go中的使用
1.导包
import (
"errors"
"github.com/dgrijalva/jwt-go"
"time"
)
2.定义结构体和一些基本信息
// MyClaims 自定义声明结构体并内嵌jwt.StandardClaims
// jwt包自带的jwt.StandardClaims只包含了官方字段
// 我们这里需要额外记录一个username字段,所以要自定义结构体
// 如果想要保存更多信息,都可以添加到这个结构体中
type MyClaims struct {
ID int `json:"id"`
Email string `json:"email"`
jwt.StandardClaims
}
const TokenExpireDuration = time.Hour * 2
var MySecret = []byte("qi66")
3.生成JWT
// GenToken 生成JWT
func GenToken(ID int, Email string) (string, error) {
// 创建一个我们自己的声明
c := MyClaims{
ID,
Email, // 自定义字段
jwt.StandardClaims{
ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(), // 过期时间
Issuer: "qi66", // 签发人
},
}
// 使用指定的签名方法创建签名对象
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
// 使用指定的secret签名并获得完整的编码后的字符串token
return token.SignedString(MySecret)
}
4.解析JWT
// ParseToken 解析JWT
func ParseToken(tokenString string) (*MyClaims, error) {
// 解析token
var mc = new(MyClaims)
token, err := jwt.ParseWithClaims(tokenString, mc, func(token *jwt.Token) (i interface{}, err error) {
return MySecret, nil
})
if err != nil {
return nil, err
}
if token.Valid { // 校验token
return mc, nil
}
return nil, errors.New("invalid token")
}
使用JWT优缺点
JWT拥有基于Token的会话管理方式所拥有的一切优势,不依赖Cookie,使得其可以防止CSRF攻击,也能在禁用Cookie的浏览器环境中正常运行。
而JWT的最大优势是服务端不再需要存储Session,使得服务端认证鉴权业务可以方便扩展,避免存储Session所需要引入的Redis等组件,降低了系统架构复杂度。但这也是JWT最大的劣势,由于有效期存储在Token中,JWT Token-旦签发,就会在有效期内-直可用,无法在服务端废止,当用户进行登出操作,只能依赖客户端删除掉本地存储的JWT Token,如果需要禁用用户,单纯使用JWT就无法做到了。