常用的认证方式分为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)
}

原文地址:http://www.cnblogs.com/davis12/p/16855030.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性