11月16日, 2018

json web token

JWT是json web token缩写。
官网 它将用户信息加密到token里,服务器不保存任何用户信息。服务器通过使用保存的密钥验证token的正确性,只要正确即通过验证。

  • 优点是在分布式系统中,很好地解决了单点登录问题,很容易解决了session共享的问题。
  • 缺点是无法作废已颁布的令牌/不易应对数据过期。

数据格式
- Header - Payload - Signature

xxxxx.yyyyy.zzzzz

Signature= alt

常用库
go get github.com/dgrijalva/jwt-go

使用实例

  • 携带数据

    // JwtClaims jwt
    type JwtClaims struct {
    	Id   int    `json:"id"`
    	Name string `json:"name"`
    	Num  string `json:"num"`
    	Role Role   `json:"role"`
    	jwt.StandardClaims
    }
    
  • 生成token

    	claims := model.JwtClaims{
    		Id:   mod.Id,
    		Name: mod.Name,
    		Num:  mod.Num,
    		Role: mod.Role,
    		StandardClaims: jwt.StandardClaims{
    			ExpiresAt: time.Now().Add(time.Hour * 2).Unix(),
    		},
    	}
    	// 保存唯一登陆信息
    	util.Save(claims.Id, claims.Rand)
    	// Create token with claims
    	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
    	// Generate encoded token and send it as response.
    	jwtStr, err := token.SignedString([]byte("xxxx"))
    	if err != nil {
    		return ctx.JSON(util.NewFail(`凭证生成失败,请重试`, err.Error()))
    	}
    
  • 验证token

    // midJwt 中间件-jwt验证
    func midJwt(next echo.HandlerFunc) echo.HandlerFunc {
    	return func(ctx echo.Context) error {
    		// query form 查找 token
    		tokenString := ctx.FormValue("token")
    		if tokenString == "" {
    			// header 查找token
    			tokenString = ctx.Request().Header.Get(echo.HeaderAuthorization)
    			if tokenString == "" {
    				ctx.JSON(util.NewErrJwt(`未发现jwt认证信息`))
    				return nil
    			}
    			// Bearer token
    			tokenString = tokenString[7:] //len("Bearer ")
    		}
    		jwtAuth := &model.JwtClaims{}
    		jwt, err := jwt.ParseWithClaims(tokenString, jwtAuth, func(token *jwt.Token) (interface{}, error) {
    			return []byte("xxxx"), nil
    		})
    		if err == nil && jwt.Valid {
    			ctx.Set("auth", jwtAuth)
    		} else {
    			return ctx.JSON(util.NewErrJwt(`对不起,请重新登陆^_^!","jwt验证失败`))
    		}
    		ctx.Response().Header().Set(echo.HeaderServer, "by zxysilent")
    		return next(ctx)
    	}
    }
    

本文链接:/posts/jwt/

-- EOF --