会话控制

2023-04-14  本文已影响0人  码农工号9527

以 go gin 为例

1. Cookie

1.1 Cookie是什么

1.2 Cookie的用途

1.3 Cookie的使用

package main

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

func AuthMiddleWare() gin.HandlerFunc {
    return func(c *gin.Context) {
        // 获取客户端cookie并校验
        if cookie, err := c.Cookie("abc"); err == nil {
            if cookie == "123" {
                c.Next()
                return
            }
        }
        // 返回错误
        c.JSON(http.StatusUnauthorized, gin.H{"error": "err"})
        // 若验证不通过,不再调用后续的函数处理
        c.Abort()
        return
    }
}

func main() {
    // 1.创建路由
    // 默认使用了2个中间件Logger(), Recovery()
    r := gin.Default()
    r.GET("/login", func(c *gin.Context) {
        // 给客户端设置cookie
        // maxAge int, 单位为秒
        // path,cookie所在目录
        // domain string,域名
        // secure 是否智能通过https访问
        // httpOnly bool  是否允许别人通过js获取自己的cookie
        c.SetCookie("abc", "123", 60, "/",
            "localhost", false, true)
        // 返回信息
        c.String(200, "Login success!")
    })
    r.GET("/home", AuthMiddleWare(), func(c *gin.Context) {
        c.JSON(200, gin.H{"data": "home"})
    })
    err := r.Run(":8000")
    if err != nil {
        return
    }
}

1.4 Cookie的缺点

2. Session

2.1 Session是什么

Session可以弥补Cookie的不足,Session必须依赖于Cookie才能使用,生成一个SessionId放在Cookie里传给客户端就可以


2.2 session模块设计

  • 本质上k-v系统,通过key进行增删改查
  • session可以存储在内存或者redis(2个版本)


3. gorilla/sessions

gorilla/sessions为自定义session后端提供cookie和文件系统session以及基础结构。

主要功能是:

代码:

package main

import (
    "fmt"
    "net/http"

    "github.com/gorilla/sessions"
)

// 初始化一个cookie存储对象
// something-very-secret应该是一个你自己的密匙,只要不被别人知道就行
var store = sessions.NewCookieStore([]byte("something-very-secret"))

func main() {
    http.HandleFunc("/save", SaveSession)
    http.HandleFunc("/get", GetSession)
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        fmt.Println("HTTP server failed,err:", err)
        return
    }
}

func SaveSession(w http.ResponseWriter, r *http.Request) {
    // Get a session. We're ignoring the error resulted from decoding an
    // existing session: Get() always returns a session, even if empty.

    // 获取一个session对象,session-name是session的名字
    session, err := store.Get(r, "session-name")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }

    // 在session中存储值
    session.Values["foo"] = "bar"
    session.Values[42] = 43
    // 保存更改
    session.Save(r, w)
}
func GetSession(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "session-name")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    foo := session.Values["foo"]
    fmt.Println(foo)
}

删除session的值:

    // 删除
    // 将session的最大存储时间设置为小于零的数即为删除
    session.Options.MaxAge = -1
    session.Save(r, w)
上一篇 下一篇

猜你喜欢

热点阅读