Go-JWT注册登录验证 | 青训营笔记

83 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天

JWT介绍

JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的、自包含的方式,用于作为JSON对象在各方之间安全地传输信息。该信息可以被验证和信任,因为它是数字签名的。

JWT的优点

  • 简洁,JWTToken 数据量小,传输速度也很快;
  • 因为 JWTToken 是以 JSON 加密形式保存在客户端的,所以 JWT 是跨语言的,原则上任何 web 形式都支持;
  • 不需要在服务端保存会话信息,也就是说不依赖于 cookie 和 session,所以没有了传统 session 认证的弊端,特别适用于分布式微服务;
  • 单点登录友好:使用 Session 进行身份认证的话,由于 cookie 无法跨域,难以实现单点登录。但是,使用 token 进行认证的话,token 可以被保存在客户端的任意位置的内存中,不一定是 cookie,所以不依赖 cookie,不会存在这些问题;
  • 适合移动端应用:使用 Session 进行身份认证的话,需要保存一份信息在服务器端,而且这种方式会依赖到 Cookie(需要 Cookie 保存 SessionId),所以不适合移动端。

安装JWT

go get github.com/golang-jwt/jwt

Github Repo:github.com/golang-jwt/…

JWT更新检查生成token

utils/jwt.go

func GenerateToken(username string, userID int, expiredSeconds int) (tokenString string, err error) {
	if expiredSeconds == 0 {
		expiredSeconds = DEFAULT_EXPIRE_SECONDS
	}
	mySigningKey := []byte("DarkGreen")
	expireAt := time.Now().Add(time.Second * time.Duration(expiredSeconds)).Unix()
	logs.Info("Tiken will be expired at ", time.Unix(expireAt, 0))

	claims := MyClaims{
		userID,
		jwt.StandardClaims{
			Issuer:    username,
			IssuedAt:  time.Now().Unix(),
			ExpiresAt: expireAt,
		},
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	tokenStr, err := token.SignedString(mySigningKey)
	if err != nil {
		return "", errors.New("error: failed to generate token")
	}
	return tokenStr, nil
}

验证前端传回来的token是否过期

func ValidateToken(tokenString string) (*MyClaims, error) {
	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{},
		func(token *jwt.Token) (interface{}, error) {
			return []byte(SecretKEY), nil
		})

	claims, ok := token.Claims.(*MyClaims)
	if ok && token.Valid {
		log.Println("ok && token valid")
		logs.Info("%v %v", claims.UserID, claims.StandardClaims.ExpiresAt)
		logs.Info("Token was issued at ", time.Now().Unix())
		logs.Info("Token will be expired at ", time.Unix(claims.StandardClaims.ExpiresAt, 0))

		return &MyClaims{
			Username:  claims.StandardClaims.Issuer,
			UserID:    claims.UserID,
			IssuedAt:  claims.StandardClaims.IssuedAt,
			ExpiresAt: claims.StandardClaims.ExpiresAt,
		}, nil
	} else {
		fmt.Println(err)
		return nil, errors.New("error: failed to validate token")
	}
}