gin使用jwt登录验证

使用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>
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Gin框架中使用JWT(JSON Web Token)可以实现验证和授权功能。JWT是一种用于在网络应用间传递信息的安全方法,它由三部分组成:header、payload和signature[^1]。 下面是在Gin框架中使用JWT的示例代码[^2]: 1. 导入所需的包: ```go import ( "github.com/gin-gonic/gin" "github.com/dgrijalva/jwt-go" ) ``` 2. 定义JWT的密钥: ```go var jwtKey = []byte("your_secret_key") ``` 3. 创建一个JWT的Claims结构体,用于存储用户的信息: ```go type Claims struct { Username string `json:"username"` jwt.StandardClaims } ``` 4. 创建一个处理登录请求的路由: ```go func login(c *gin.Context) { var loginData LoginData if err := c.ShouldBindJSON(&loginData); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid request"}) return } // 验证用户名和密码 if loginData.Username == "admin" && loginData.Password == "password" { // 创建JWT的Claims claims := &Claims{ Username: loginData.Username, StandardClaims: jwt.StandardClaims{ ExpiresAt: time.Now().Add(time.Hour * 24).Unix(), // 设置过期时间 }, } // 创建JWT token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims) tokenString, err := token.SignedString(jwtKey) if err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to generate token"}) return } // 返回JWT给客户端 c.JSON(http.StatusOK, gin.H{"token": tokenString}) } else { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid credentials"}) } } ``` 5. 创建一个需要身份验证的路由: ```go func protectedRoute(c *gin.Context) { // 从请求头中获取JWT authHeader := c.GetHeader("Authorization") if authHeader == "" { c.JSON(http.StatusUnauthorized, gin.H{"error": "Missing authorization header"}) return } // 解析JWT tokenString := authHeader[7:] // 去除Bearer前缀 claims := &Claims{} token, err := jwt.ParseWithClaims(tokenString, claims, func(token *jwt.Token) (interface{}, error) { return jwtKey, nil }) if err != nil { if err == jwt.ErrSignatureInvalid { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token signature"}) return } c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid token"}) return } if !token.Valid { c.JSON(http.StatusUnauthorized, gin.H{"error": "Invalid token"}) return } // 验证通过,继续处理请求 c.JSON(http.StatusOK, gin.H{"message": "Protected route"}) } ``` 6. 在路由中注册处理函数: ```go func main() { r := gin.Default() r.POST("/login", login) r.GET("/protected", protectedRoute) r.Run(":8080") } ``` 以上代码演示了在Gin框架中使用JWT进行身份验证和授权的基本流程。用户可以通过发送登录请求获取JWT,然后在需要身份验证的路由中将JWT放入请求头中进行验证

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐梦想之路_随笔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值