go-gin集成session认证

常用的认证方式分为cookie/session/jwt,本文将演示golang的gin框架中如何集成session完成用户认证。

示例目录结构:

项目main入口:

package main

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

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

	engine.Use(api.EnableCookieSession()) // cookie as store
	engine.POST("/login", api.Login)

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

	engine.Run(":8080")
}

认证接口:

package api

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

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
	_ = ctx.ShouldBindBodyWith(&params, binding.JSON)
	if params.Username == "test" && params.Password == "123456" {
		sessionID := SaveSession(ctx, params.Username)
		ctx.JSON(200, gin.H{
			"code": 0,
			"msg": "Login success",
			"sessionID": sessionID,
		})
		return
	}

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

中间件:

package api

import (
	"crypto/sha256"
	"fmt"
	"github.com/gin-contrib/sessions"
	"github.com/gin-contrib/sessions/cookie"
	"github.com/gin-gonic/gin"
	"strconv"
	"time"
)

func AuthSessionMiddleware() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		// extract session
		sessionID := ctx.Request.Header.Get("Sessionid")
		if sessionID == "" {
			ctx.JSON(401, gin.H{
				"code": 1,
				"msg": "unauthorized",
			})
			ctx.Abort()
			return
		}
		// set simple var
		ctx.Set("sessionID", sessionID)
		// validate session:1.check cache 2.check database // TODO

		ctx.Next()
	}
}
const KEY = "SESSIONSECRET"

func EnableCookieSession() gin.HandlerFunc {
	store := cookie.NewStore([]byte(KEY))
	return sessions.Sessions("Sample", store)
}

// register and login will save session
func SaveSession(ctx *gin.Context, username string) string {
	session := sessions.Default(ctx)
	// simple encrypt: sha256(usename + string(timestamp))
	contact := username + strconv.FormatInt(time.Now().UnixMilli(), 10)
	sum := sha256.Sum256([]byte(contact))
	val := fmt.Sprintf("%x", sum)
	session.Set("sessionID", val)
	session.Save()
	sessionID := session.Get("sessionID").(string)
	ctx.Writer.Header().Set("sessionID", sessionID)
	return sessionID
}

// logout will clear session
func ClearSession(ctx *gin.Context)  {
	session := sessions.Default(ctx)
	session.Clear()
	session.Save()
}

func HasSession(ctx *gin.Context) bool {
	session := sessions.Default(ctx)
	if val := session.Get("sessionID"); val == nil {
		return false
	}
	return true
}

func GetSession(ctx*gin.Context) string {
	session := sessions.Default(ctx)
	val := session.Get("sessionID")
	if val.(string) == "" {
		return ""
	}
	return val.(string)
}

posted on 2022-11-03 16:44  进击的davis  阅读(444)  评论(0编辑  收藏  举报

导航