gin使用jwt登录验证

发布时间:2024年01月08日

使用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

<template>
  <div id="app">
    <Button @click="getUserInfo">获取用户信息</Button>
  </div>
</template>
文章来源:https://blog.csdn.net/qq_44472790/article/details/135446952
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。