大项目笔记(2) | 青训营笔记

121 阅读2分钟

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

token

定义

Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。

作用

  • 防止表单重复提交
  • 用来作身份验证

流程

  • 用户首次登录,将输入的账号和密码提交给服务器
  • 服务器对输入内容进行校验,若账号和密码匹配则验证通过,登录成功,并生成一个token值,将其保存到数据库,并返回给客户端
  • 客户端拿到返回的token值将其保存在本地(如cookie/localStorage),作为公共参数,以后每次请求服务器时都携带该token(放在响应头里),提交给服务器进行校验
  • 服务器接收到请求后,首先验证是否携带token,若携带则取出请求头里的token值进行匹配校验,若token值相同则登录成功,且当前正处于登录状态,此时正常返回数据,让app显示数据;若不存在或两个值不一致,则说明原来的登录已经失效,此时返回错误状态码

代码

//生成Token
func (u *User) NewToken() string {
	expiresTime := time.Now().Unix() + int64(86400)
	//fmt.Printf("expiresTime: %v\n", expiresTime)
	id64 := int64(u.Model.ID)
	//fmt.Printf("id: %v\n", strconv.FormatInt(id64, 10))
	claims := jwt.StandardClaims{
		Audience:  u.UserName,
		ExpiresAt: expiresTime,
		Id:        strconv.FormatInt(id64, 10),
		IssuedAt:  time.Now().Unix(),
		Issuer:    "tiktok",
		NotBefore: time.Now().Unix(),
		Subject:   "token",
	}
	var jwtSecret = []byte("tiktok")
	tokenClaims := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	if token, err := tokenClaims.SignedString(jwtSecret); err == nil {
		println("generate token success!\n")
		return token
	} else {
		println("generate token fail\n")
		return "fail"
	}
}
// 对token进行解析
func parseToken(token string) (*jwt.StandardClaims, error) {
	jwtToken, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(token *jwt.Token) (i interface{}, e error) {
		return []byte("tiktok"), nil
	})
	if err == nil && jwtToken != nil {
		if claim, ok := jwtToken.Claims.(*jwt.StandardClaims); ok && jwtToken.Valid {
			return claim, nil
		}
	}
	return nil, err
}

// 返回id
func (usi *UserServiceImpl) GetparseTokens(token string) (uint, error) {
	tokens, err := parseToken(token)
	if err != nil {
		return 0, err
	}
	userid, err := strconv.ParseInt(tokens.Id, 10, 64)
	if err != nil {
		return 0, err
	}
	return uint(userid), nil

}