首页 > 其他分享 >go-gin集成jwt认证

go-gin集成jwt认证

时间:2022-11-03 18:36:38浏览次数:51  
标签:code return ctx jwt token go gin

今天趁热打铁,把cookie/session/jwt集成go-gin框架的认证方式,一鼓作气全code一遍,life is short, show you the code.

示例目录结构:

项目入口:

package main

import (
	"gin-any/api"
	"github.com/gin-gonic/gin"
)

func main()  {
	engine := gin.Default()

	engine.POST("/login", api.Login)

	engine.GET("/user", api.AuthJWTMiddleware(), api.User)

	engine.Run(":8080")
}

接口代码:

package api

import (
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"net/http"
)

type ReqParams struct {
	Username string `json:"username"`
	Password string `json:"password"`
}

func User(ctx *gin.Context)  {
	ctx.JSON(200, gin.H{
		"code": 0,
		"msg": "success",
		"data": map[string]string{"user": "test"},
	})
}

func Login(ctx *gin.Context)  {
	var params ReqParams
	err := ctx.ShouldBindBodyWith(&params, binding.JSON)
	if err != nil {
		ctx.JSON(http.StatusOK, gin.H{"code": 1, "msg": "Invalid parameters."})
		return
	}
	if params.Username == "test" && params.Password == "123456" {
		// generate token
		token, _ := GenerateToken(params.Username)
		ctx.JSON(200, gin.H{
			"code": 0,
			"msg": "Login success",
			"data": gin.H{"token": token},
		})
		return
	}

	ctx.JSON(401, gin.H{
		"code": 1,
		"msg": "Login failed",
	})
}

中间件代码:

package api

import (
	"crypto/sha256"
	"fmt"
	"github.com/dgrijalva/jwt-go"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"github.com/pkg/errors"
	"net/http"
	"strconv"
	"strings"
	"time"
)

func AuthJWTMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// extract jwt, Authorization: "Bearer " + token
		authHeader := ctx.Request.Header.Get("Authorization")
		if authHeader == "" { // return in advance
			ctx.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg": "Request header has no auth",
			})
			ctx.Abort()
			return
		}
		// parse jwt
		parts := strings.SplitN(authHeader, " ", 2)
		if !(len(parts) == 2 && parts[0] == "Bearer") {
			ctx.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg": "Request header auth wrong format",
			})
			ctx.Abort()
			return
		}
		mc, err := ParseToken(parts[1])
		if err != nil {
			ctx.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg": "Invalid token",
			})
			ctx.Abort()
			return
		}
		// if needed, inject username into context
		ctx.Set("username", mc.Username)
		// pass request
		ctx.Next()
	}
}

type MyClaims struct {
	Username string `json:"username"`
	jwt.StandardClaims
}

const TokenExpireDuration = time.Second * 30

var MySecret = []byte("gin-jwt")

// generate token
func GenerateToken(username string) (string, error) {
	// create self claims
	c := MyClaims{
		username,
		jwt.StandardClaims{
			ExpiresAt: time.Now().Add(TokenExpireDuration).Unix(),
			Issuer: "project",
		},
	}
	// specific sign method to create obj
	t := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
	return t.SignedString(MySecret)
}

// parse token
func ParseToken(tokenString string) (*MyClaims, error) {
	// parse token
	token, err := jwt.ParseWithClaims(tokenString, &MyClaims{}, func(token *jwt.Token) (interface{}, error) {
		return MySecret, nil
	})
	if err != nil {
		return nil, err
	}
	if claims, ok := token.Claims.(*MyClaims); ok && token.Valid {
		return claims, nil
	}
	return nil, errors.New("Invalid token")
}

以下是postman测试情况:
login接口:

后续请求接口-过期token:

标签:code,return,ctx,jwt,token,go,gin
From: https://www.cnblogs.com/davis12/p/16855418.html

相关文章

  • 【MongoDB】入门
    通过docker安装dockerrun-d-p27017:27017--namemongo01-v/docker/mongo/config:/data/configdb-v/docker/db:/data/dbmongo-eMONGO_INITDB_ROOT_USERNAME=ad......
  • nginx
    一、实现原理异步,非阻塞,使用了epoll和大量的底层代码优化。nginx采用linux的epoll模型,epoll模型基于事件驱动机制,可以监控多个事件是否准备完毕,如果可以,就放入epoll队列......
  • Django_获取api接口的传参
    当参数为form-data或者x-www-form-urlencoded类型时,使用request.POST获取到参数获取参数方式request.POST.get('username')当参数为raw类型时,使用request.body获取......
  • 039nginx reload本质
    一、nginxreload所做的事情首先会-t进行检查,假如检查失败,nginx好像是不会重启worker进程的;检查通过nginx会启动新的worker进程,并shutdown老的worker进程;如下图所示......
  • gin框架中如何实现流式下载
    作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!cnblogs博客zhihuGithub公众号:一本正经的瞎扯团队中之前的文件下载做得比较复杂,因为担心量太大,是后台做......
  • django model字段类型
    1、models.AutoField自增列=int(11)如果没有的话,默认会生成一个名称为id的列,如果要显示的定义一个自增列,必须把该列设置为主键(primary_key=True)2、models.CharFie......
  • golang封装http get函数请求并且携带header头信息
    有遇到这种需求,golang发送GET请求,携带header头信息,比如header里带着验证token封装函数如下://Get请求携带headerfuncGetWithHeader(urlstring,headersmap[string]st......
  • nginx前后端代理配置
    #前端页面代理location/{roothtml/h5;indexindex.htmlindex.htm;}#后端静态文件代理location/age/static{......
  • 【Golang标准库】flag
    参考:flag学习在Golang程序中有很多种方法来处理命令行参数。简单的情况下可以不使用任何库,直接处理os.Args;其实Golang的标准库提供了flag包来处理命令行参数;还有第......
  • 写给关系数据库开发者的 TDengine 入门指南
    MySQL是中国开发者最熟悉的开源数据库产品,在很多开发者心中MySQL就是关系数据库的代名词。开发者们对MySQL数据库的的特性已经非常熟悉了。TDengine (https://github......