使用github.com/dgrijalva/jwt-go包,gihub地址:https://github.com/dgrijalva/jwt-go
安装包
go get -u github.com/dgrijalva/jwt-go
简单封装生成token、验证token有效、通过Authorization解析token三个函数
models/jwt.go
package modelsimport ("net/http""strings""time""github.com/dgrijalva/jwt-go""github.com/gin-gonic/gin"
)// 定义一个结构体,这个结构体需要继承 jwt.StandardClaims 结构体
type MyClaims struct {Uid int // 用户idUserName string // 用户名jwt.StandardClaims
}// 定义key
var jwtKey = []byte("a_secret_test123456")// 过期时间24小时
var expireTime = time.Now().Add(24 * time.Hour).Unix()// 生成token
func GenerateToken(c *gin.Context, uid int, username string) (string, error) {// 创建MyClaims实例myClaims := MyClaims{uid, // 用户idusername, // 用户名jwt.StandardClaims{ExpiresAt: expireTime,Issuer: "test",},}// 创建签名对象tokenObj := jwt.NewWithClaims(jwt.SigningMethodHS256, myClaims)// 使用指定的jwtKey签名获取完整编码字符串tokentokenStr, err := tokenObj.SignedString(jwtKey)if err != nil {c.JSON(http.StatusOK, gin.H{"message": "生成token失败","success": false,})return "", err}// 返回tokenreturn tokenStr, nil// c.JSON(http.StatusOK, gin.H{// "message": "获取token成功",// "token": tokenStr,// "success": true,// })
}// 获取Authorization的值
func GetAuthorizationToken(c *gin.Context) string {// 获取接口传递过来的AuthorizationtokenInfo := c.Request.Header.Get("Authorization")var tokenStr = ""if len(tokenInfo) > 0 {// 截取tokentokenStr = strings.Split(tokenInfo, " ")[1]}// 返回tokenreturn tokenStr
}// 验证token是否有效
func ParseToken(tokenStr string) (*jwt.Token, *MyClaims, error) {myClaims := &MyClaims{}token, err := jwt.ParseWithClaims(tokenStr, myClaims, func(token *jwt.Token) (i interface{}, err error) {return jwtKey, nil})return token, myClaims, err
}
登录简单逻辑测试
controller/api.go
package apiimport ("fmt""gin-jwt-demo/models""net/http""github.com/gin-gonic/gin"
)type V1ApiController struct{}// 登录
func (v V1ApiController) Login(c *gin.Context) {uid := 1234567username := "zhangsan"// 这块省略账号密码登录逻辑...// 走到这说明登录成功,生成tokentokenStr, err := models.GenerateToken(c, uid, username)if err != nil {c.JSON(http.StatusOK, gin.H{"message": "登录失败","token": tokenStr,"success": false,})return}// 将token、uid、username存到cookie中c.SetCookie("token", tokenStr, 3600, "/", "localhost", false, false)c.SetCookie("uid", fmt.Sprintf("%d", uid), 3600, "/", "localhost", false, false)c.SetCookie("username", username, 3600, "/", "localhost", false, false)c.JSON(http.StatusOK, gin.H{"message": "登录成功","token": tokenStr,"uid": uid,"username": username,"success": true,})
}// 获取用户信息接口 需要身份授权验证
func (v V1ApiController) UserInfo(c *gin.Context) {// 从header获取Authorizationauthorization := models.GetAuthorizationToken(c)// 不存在token 校验token是否有效tokenObj, userInfos, err := models.ParseToken(authorization)// 校验authorization是否为空if authorization == "" || err != nil {c.JSON(http.StatusOK, gin.H{"message": "未登录","success": false,})return}c.JSON(http.StatusOK, gin.H{"message": "成功获取用户信息","uid": userInfos.Uid,"username": userInfos.UserName,"token": tokenObj.Raw,"success": true,})
}
router/router.go
package routerimport ("gin-jwt-demo/controller/api""github.com/gin-gonic/gin"
)func ApiRouterInit(r *gin.Engine) {// v1接口apiV1Routers := r.Group("/api/v1"){// 登录接口apiV1Routers.GET("/login", api.V1ApiController{}.Login)// 获取用户信息接口apiV1Routers.GET("/userinfo", api.V1ApiController{}.UserInfo)}
main.go
package mainimport ("gin-jwt-demo/models""github.com/gin-gonic/gin"
)func main() {// 路由初始化r := gin.Default()// 解决cors跨域//配置gin允许跨域请求r.Use(models.Cors())// api路由注册ApiRouterInit(r)// 服务启动r.Run(":9999")
}
vue项目发送axios请求携带Authorization
js
import Cookies from "js-cookie";
import axios from "axios";
axios.defaults.baseURL = "http://localhost:9999";const getUserInfo = () => {// 获取cookieaxios.get("/api/v1/userinfo", {headers: {Authorization: "Bearer " + Cookies.get("token"),},}).then((res) => {console.log("获取用户信息:", res);});
};
template
<template><div id="app"><Button @click="getUserInfo">获取用户信息</Button></div>
</template>