{ "typ":"jwt" "alg":"HS256" }Payload 是记录我们可能需要的信息,除了现有已提供的标准的Claims ,还可以自定义一些可能需要的字段,比如 userId,userName 等。claims 是可以被解密的,所以不要存放重要而敏感的的信息。
// --- 标准 iss (issuer): JWT 的签发人 exp (expiration time): 过期时间 sub (subject): 主题,该jwt所面向的用户 aud (audience): 受众 接收该 jwt的一方 nbf (Not Before): 生效时间 iat (Issued At): 签发时间 jti (JWT ID): 编号 // 自定义 Claims userId userNameSignature 是由Header 中声明的加密算法进行生成的签名
创建 jwtMaker 文件,定义 Maker 接口来规范 jwtMaker 只需要进行创建 CreateToken 和验证 VerifyToken两个方法。可以使用现在比较常用的一个jwt 包来完成 Token 的 ,直接获取:go get github.com/dgrijalva/jwt-go。
type CustomClaims struct { // 堆代码 duidaima.com ID uuid.UUID UserName string IssuedAt time.Time ExpiresAt time.Time } func NewCustomClaims(userName string, duration time.Duration)( * CustomClaims, error) { tokenId, err: = uuid.NewRandom() if err != nil { return nil, err } customClaim: = & CustomClaims { ID: tokenId, UserName: userName, IssuedAt: time.Now(), ExpiresAt: time.Now().Add(duration), } return customClaim, nil } func(c * CustomClaims) Valid() error { if time.Now().After(c.ExpiresAt) { return errors.New("token has expired") } return nil }创建签名
func(j * JwtMaker) CreateToken(userName string, duration time.Duration)(string, error) { payload, err: = NewCustomClaims(userName, duration) if err != nil { return "", err } jwtToken: = jwt.NewWithClaims(jwt.SigningMethodHS256, payload) return jwtToken.SignedString([] byte(j.SecretKey)) }验证签名
func(j * JwtMaker) VerifyToken(token string)( * CustomClaims, error) { var result = new(CustomClaims) jwtToken, err: = jwt.ParseWithClaims(token, result, func(token * jwt.Token)(interface {}, error) { if _, ok: = token.Method.( * jwt.SigningMethodHMAC); !ok { return nil, errors.New("无效 Token") } else { return [] byte(j.SecretKey), nil } }) if err != nil { return nil, err } // 校验 token if jwtToken.Valid { return result, nil } if err = result.Valid(); err != nil { return nil, fmt.Errorf("token 已过期") } return nil, fmt.Errorf("invalid token") }
验证签名时,通过解析 token ,验证 token 是否有效,再验证是否过期。验证Token 是用在用户登录后所有请求都需要携带 token ,然后服务端获取到 token 再进行验证过。
等等还有其他的使用场景,使用token 可以自由安全支持多端登录的机制。