使用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 models
import (
"net/http"
"strings"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)
// 定义一个结构体,这个结构体需要继承 jwt.StandardClaims 结构体
type MyClaims struct {
Uid int // 用户id
UserName 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, // 用户id
username, // 用户名
jwt.StandardClaims{
ExpiresAt: expireTime,
Issuer: "test",
},
}
// 创建签名对象
tokenObj := jwt.NewWithClaims(jwt.SigningMethodHS256, myClaims)
// 使用指定的jwtKey签名获取完整编码字符串token
tokenStr, err := tokenObj.SignedString(jwtKey)
if err != nil {
c.JSON(http.StatusOK, gin.H{
"message": "生成token失败",
"success": false,
})
return "", err
}
// 返回token
return tokenStr, nil
// c.JSON(http.StatusOK, gin.H{
// "message": "获取token成功",
// "token": tokenStr,
// "success": true,
// })
}
// 获取Authorization的值
func GetAuthorizationToken(c *gin.Context) string {
// 获取接口传递过来的Authorization
tokenInfo := c.Request.Header.Get("Authorization")
var tokenStr = ""
if len(tokenInfo) > 0 {
// 截取token
tokenStr = strings.Split(tokenInfo, " ")[1]
}
// 返回token
return 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 api
import (
"fmt"
"gin-jwt-demo/models"
"net/http"
"github.com/gin-gonic/gin"
)
type V1ApiController struct{}
// 登录
func (v V1ApiController) Login(c *gin.Context) {
uid := 1234567
username := "zhangsan"
// 这块省略账号密码登录逻辑...
// 走到这说明登录成功,生成token
tokenStr, 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获取Authorization
authorization := 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 router
import (
"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 main
import (
"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 = () => {
// 获取cookie
axios
.get("/api/v1/userinfo", {
headers: {
Authorization: "Bearer " + Cookies.get("token"),
},
})
.then((res) => {
console.log("获取用户信息:", res);
});
};
template