token用于验证用户是否登录或者说有权限进行操作。当访问一个需要登录才能操作的功能,应该提示没有权限或者调转到登录页。
1、先说登录成功后生成token
先安装第三方库github.com/golang-jwt/jwt
下面是生成token的方法,uservo参数用于存储自定义的内容。jwt.SigningMethodHS256代表的是加密算法,exp是到期时间,iat是起止时间,appKey是密钥。最后tokenString就是生成的token,里面主要包含到期时间和自定义的内容。生成的token放入cookie就可以了。
func SetToken(uservo Uservo) string {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"uservo": uservo,
"exp": time.Now().Add(3600 * 24 * 7 * time.Second).Unix(),
"iat": time.Now().Unix(),
})
tokenString, _ := token.SignedString([]byte(appKey))
return tokenString
}
2、验证token
也就是在访问任何地址前,需要先验证token是否有效,有效继续,无效的话就重定向到登录页。
这里面主要就是下面的中间件,先过滤一些不需要验证的地址,如果是这些地址就继续下一个中间件。先从cookie获取token,如果不存在或者不正确就转向登录页,否则就存储到上下文中。
func MyMiddleware(rw http.ResponseWriter, r *http.Request, next http.HandlerFunc) {
//fmt.Println("url", r.URL.Path)
if r.URL.Path == "/login" || r.URL.Path == "/" || strings.Contains(r.URL.Path, "/lib/") || strings.Contains(r.URL.Path, "/static/") || strings.Contains(r.URL.Path, "/temp/") {
next(rw, r)
} else {
token, err := r.Cookie("token")
if err != nil {
t, error := template.ParseFiles("templates/login.html")
if error != nil {
fmt.Println(error.Error())
}
t.Execute(rw, nil)
}
tcontext := context.WithValue(context.Background(), "token", usermap)
rcontext := r.WithContext(tcontext)
next(rw, rcontext)
}
}
3、从token中获取自定义内容
func GetToken(tokenString string) (usermap interface{}, err error) {
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
return []byte(appKey), nil
})
if token.Valid {
usermap = token.Claims.(jwt.MapClaims)["uservo"]
return usermap, nil
} else if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return usermap, errors.New("token错误")
} else if ve.Errors&(jwt.ValidationErrorExpired|jwt.ValidationErrorNotValidYet) != 0 {
return usermap, errors.New("token错误")
} else {
return usermap, errors.New("token错误")
}
} else {
return usermap, errors.New("token错误")
}
}
4、在上下文中使用token自定义内容
token := r.Context().Value("token").(map[string]interface{})
operid := token["id"]