go-gin集成cookie认证
cookie的作用不用细说,作为简单而基础的认证方法,以前用的比较多,随着技术的演进,cookie的问题也出现,比如跨域、安全问题等。
本文基于golang语言的gin框架,演示cookie在gin框架的集成使用,作为一个学习记录。
示例目录结构:
先看看项目入口:
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.AuthCookie(), api.User) // 在登录的后续接口中将cookie鉴权以中间件形式注入
engine.Run(":8080")
}
登录handler:
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(¶ms, binding.JSON) // 可重复绑定,写入ctx
if params.Username == "test" && params.Password == "123456" { // 简单check下user信息,实际要结合数据库
ctx.SetCookie("user", "test", 3600, "/", "localhost", false, true) // check成功后,设置cookie
ctx.JSON(200, gin.H{
"code": 0,
"msg": "Login success",
})
return
}
ctx.JSON(401, gin.H{ // check失败,返回登录失败信息
"code": 1,
"msg": "Login failed",
})
}
cookie中间件:
package api
import "github.com/gin-gonic/gin"
func AuthCookie() gin.HandlerFunc {
return func(ctx *gin.Context) {
cookie, err := ctx.Request.Cookie("user") // 尝试提取cookie,注意此name与下文的SetCookie的参数name是一致的
if err == nil { // refresh cookie,提取成功,更新cookie
ctx.SetCookie(cookie.Name, cookie.Value, cookie.MaxAge, cookie.Path, cookie.Domain, cookie.Secure, cookie.HttpOnly)
ctx.Next() // 可进行后续请求
} else { // auth not pass,没有cookie,认为auth失败,返回未认证信息,实际应该redirect到登录界面
ctx.Abort()
ctx.JSON(401, gin.H{
"code": 1,
"msg": "Not authenticate.",
})
return
}
}
}
以下是postman测试情况:
先登录:
然后添加Set-Cookie再进行后续请求: