(进阶)golang+gin+jwt实现用户登录获取token
-
1.获取token
POST请求参数
{ "name":"xj", "pwd":"xj123456" }
golang api router:
// 获取Token router.POST("/api/getToken", service.GetApiTokenService)
service:
//请求参数结构体 type GetTokenRequestParam struct { Name string `json:"Name"` Pwd string `json:"Pwd"` } //自定义密钥 var tokenApiSecret = "itxj980420" //获取token func GetTokenService(c *gin.Context) { reqModel := GetTokenRequestParam{} errByBind := c.Bind(&reqModel) if errByBind != nil { c.JSON(http.StatusOK, gin.H{ "code": http.StatusBadRequest, "message": "失败", "token": "", }) return } //参数非空校验 if common.IsEmpty(reqModel.Name) || common.IsEmpty(reqModel.Pwd) { c.JSON(http.StatusOK, gin.H{ "code": http.StatusBadRequest, "message": "账号、密码不能为空!!!", "token": "", }) return } //TODO 添加其他校验如账号密码校验;签名校验等其他自定义参数校验 //jwt token header 法加密 token := jwt.New(jwt.SigningMethodHS256) //jwt claims 载荷 //jti:该jwt的唯一标识 //iss:该jwt的签发者 //iat:该jwt的签发时间 //aud:该jwt的接收者 //sub:该jwt的面向的用户 //nbf:该jwt的生效时间,可不设置,若设置,一定要大于当前Unix UTC,否则token将会延迟生效 // exp:该jwt的过期时间 Unix() claims := make(jwt.MapClaims) claims["jti"] = reqModel.Name + reqModel.Pwd + strconv.Itoa(int(time.Now().Unix())) claims["iss"] = "itxj" claims["iat"] = time.Now() claims["aud"] = reqModel.Name claims["sub"] = reqModel.Name claims["nbf"] = time.Now().Unix() claims["exp"] = time.Now().Add(time.Hour * time.Duration(24)).Unix() //Payload载荷 token.Claims = claims //密钥加密 tokenStr, errBySignToken := token.SignedString([]byte(tokenApiSecret)) //token 生成失败 if errBySignToken != nil { c.JSON(http.StatusOK, gin.H{ "code": http.StatusUnauthorized, "message": "Error while signing the token!", "token": "", }) return } //success c.JSON(http.StatusOK, gin.H{ "code": http.StatusOK, "message": "Success!", "token": tokenStr, }) return }
-
2.路由中间件校验token
GET 请求:
http://ip:port/api/validateToken/:key
Param: key:载荷中的key
//请求
header 里面
"Token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJ4aiIsImV4cCI6MTU3Nzg2NjU1NiwiaWF0IjoiMjAxOS0xMi0zMVQxNjoxNTo1NS4zNDUyODkrMDg6MDAiLCJpc3MiOiJpdHhqIiwianRpIjoieGppdHhqMTU3Nzc4MDE1NCIsIm5iZiI6MTU3Nzc4MDE1NSwic3ViIjoieGoifQ.zg0FtD4Ovk0GysPSxn2IZfFkvA6KmqbczDPu9zQDFk4"
gin router api
router.GET("/api/validateToken/:key", service.ValidateTokenService(), service.TestValidateTokenService)
路由中间件—-:校验token是否有效
//路由中间件校验token
func ValidateTokenService() gin.HandlerFunc {
return func(c *gin.Context) {
token, err := request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor, func(token *jwt.Token) (i interface{}, e error) {
return []byte(tokenApiSecret), nil
})
if err != nil {
c.Abort()
c.JSON(http.StatusOK, gin.H{
"code": http.StatusUnauthorized,
"message": "fail",
"error": "Unauthorized!",
})
return
}
if !token.Valid {
c.Abort()
c.JSON(http.StatusOK, gin.H{
"code": http.StatusUnauthorized,
"message": "fail",
"error": "An invalid Token!",
})
return
}
c.Next()
}
}
service:
//获取token中的账号
func TestValidateTokenService(c *gin.Context) {
sub := c.Param("key")
token, _ := GetTokenFromRequest(c)
claimsVal := GetValueFromTokenClaims(sub, token.Claims)
c.JSON(http.StatusOK, gin.H{
"code": http.StatusOK,
"message": "成功",
"claimsVal": claimsVal,
})
return
}
//从请求头中获取token
func GetTokenFromRequest(c *gin.Context) (token *jwt.Token, err error) {
token, err = request.ParseFromRequest(c.Request, request.AuthorizationHeaderExtractor,
func(token *jwt.Token) (interface{}, error) {
return []byte(tokenApiSecret), nil
})
return token, err
}
//根据key从载荷中获取数据
func GetValueFromTokenClaims(key string, claims jwt.Claims) string {
v := reflect.ValueOf(claims)
if v.Kind() == reflect.Map {
for _, k := range v.MapKeys() {
value := v.MapIndex(k)
if fmt.Sprintf("%s", k.Interface()) == key {
return fmt.Sprintf("%v", value.Interface())
}
}
}
return ""
}
有疑问加站长微信联系(非本文作者)