首先来说,什么时候生成token
在用户登录的时候我们就要生成token,并且把这个token返回给前端
func (c *UserController) Login() {
var result objecth.ManageUserResponse
// get access param form request data
reqParam := &ReqParamLogin{}
err := c.ParseForm(reqParam)
if err != nil {
result.At = time.Now().Unix()
result.Code = objecth.HTTPErrnoInvalidFormat
c.Data["json"] = result
c.ServeJSON()
return
}
// gen jwt token
tokenStr, err := genToken(u.AccessID, u.AccessKey) //在这个方法里生成token
if err != nil {
result.At = time.Now().Unix()
result.Code = objecth.HTTPErrno500
c.Data["json"] = result
c.ServeJSON()
return
}
result.At = time.Now().Unix()
result.Code = objecth.HTTPErrnoOK
result.Result = &objecth.ManageToken{Token: tokenStr}
c.Data["json"] = result
c.ServeJSON()
}
首先我们要生成token
func genToken(accessID, accessKey string) (tokenStr string, err error) {
// gen jwt token
jwtPayload := map[string]interface{}{
// standard
"iss": 123,
"sub": 123,
"aud": 123,
"iat": time.Now().Unix(),
// user-defined
"name": "123456",
"access_id": 123,
"admin": true,
}
tokenStr, err = jwtutils.EncoderJ WTString([]byte(accessKey), jwtPayload, time.Now().Add(time.Duration(config.GCfg.JWT.ExpirationTime)*time.Second).Unix())//生成token
if err != nil {
return "", err
}
err = jwtutils.SetTokenToCacheWithExp(tokenStr, []byte(accessKey), int64(config.GCfg.JWT.ExpirationTime))//那这个token存入到缓存中
if err != nil {
return "", err
}
return tokenStr, nil
}
token生成
// EncoderJWTString 加密获取JWT字符串
func EncoderJWTString(key []byte, payload map[string]interface{}, exp int64) (tokenStr string, err error) {
jwtToken := jwt.New(jwt.SigningMethodHS256)
claims := jwtToken.Claims.(jwt.MapClaims)
for k, v := range payload {
claims[k] = v
}
claims["exp"] = exp
tokenStr, err = jwtToken.SignedString(key)
if err != nil {
return "", err
}
return tokenStr, nil
}
生成之后返回给前段,怎么使用呢这个时候就需要了
当我们跳转到一个页面,或者说我们过了一会重新打开这个网页,我们只需要验证tonken是否存在,存在就能正常访问,不存在就需要重新登录
在一个路由组里面是这样的
nsV1Manage := web.NewNamespace("/v1/manage",
web.NSBefore(apiJwtAuth),
web.NSRouter("/list", &manage.DateController{}, "get:Getlist"),
web.NSBefore(apiJwtAuth),就是验证token
// apiJwtAuth api jwt auth
func apiJwtAuth(ctx *context.Context) {
// get jwt token herader 'Authorization'
auth := ctx.Input.Header("Authorization")
_, err := jwtutils.GetTokenByAuthorization(auth)
if err != nil {
if config.GCfg.Env == "development" {
log.GLog.Error("[api-jwt-auth] models GetTokenByAuthorization error, %s", err)
}
ctx.ResponseWriter.WriteHeader(objecth.HTTPErrno403)
r := objecth.Response{At: time.Now().Unix(), Code: objecth.HTTPErrnoIllegalToken}
if config.GCfg.Env == "development" {
b, err := json.MarshalIndent(r, "", " ")
if err != nil {
log.GLog.Error("[api-jwt-auth] json MarshalIndent error, %s", err)
}
ctx.WriteString(string(b))
return
}
b, err := json.Marshal(r)
if err != nil {
log.GLog.Error("[api-jwt-auth] json Marshal error, %s", err)
}
ctx.WriteString(string(b))
return
}
} else {
ctx.Output.Header("Allow", "GET,POST")
ctx.WriteString("")
}
其中_, err := jwtutils.GetTokenByAuthorization(auth)就是token的一个验证
// GetTokenByAuthorization 根据HTTP Header: Authorization, 获取解码后的token值
// auth 为 Bearer eyJ...CJ9.eyJ...jR9.8ge...3hw
func GetTokenByAuthorization(auth string) (token *jwt.Token, err error) {
var tokenStr string
// get accessKey from cache
accessKey, err := JWTCacheGet(tokenStr)//在缓存中查找这个token
if err != nil {
return nil, err
}
token, err = DecoderJWTString(accessKey, tokenStr)
if err != nil {
return nil, err
}
return token, nil
}
存在就对token进行解密
// DecoderJWTString 解密JWT字符串
func DecoderJWTString(key []byte, tokenStr string) (token *jwt.Token, err error) {
token, err = jwt.Parse(tokenStr, func(t *jwt.Token) (interface{}, error) {
// Check the signing method
if t.Method.Alg() != "HS256" {
return nil, fmt.Errorf("unexpected jwt signing method= %v", t.Header["alg"])
}
return key, nil
})
if err == nil && token.Valid {
return token, nil
}
return nil, errors.New("token is illegal, " + err.Error())
}
当返回的token没问题是我们就可以访问这个借口了