会话
会话使您能够在多个请求中存储用户信息,在本质上无状态的HTTP协议中提供有状态的体验。 这些用户信息被持久地存储在服务器端。 Goravel提供了一个统一的接口来与各种持久存储驱动程序交互。
配置
session
配置文件位于config/session.go
。 默认驱动程序是file
,它将会话存储在storage/framework/sessions
目录中。 Goravel允许您通过实现contracts/session/driver
接口来创建自定义的session
驱动程序。
注册中间件
默认情况下,Goravel不会自动启动会话。 然而,它提供了启动会话的中间件。 你可以在 app/http/kernel.go
文件中注册会话中间件以将其应用于所有路由,或者将其添加到特定路由:
import (
"github.com/goravel/framework/contracts/http"
"github.com/goravel/framework/session/middleware"
)
func (kernel Kernel) Middleware() []http.Middleware {
return []http.Middleware{
middleware.StartSession(),
}
}
与会话交互
检索数据
你可以使用 Get
方法从会话中检索数据。 如果该值不存在,将返回 nil
。
value := ctx.Request().Session().Get("key")
你也可以将默认值作为第二个参数传递给 Get
方法。 如果指定的键在会话中不存在,将返回这个值:
value := ctx.Request().Session().Get("key", "default")
检索所有数据
如果您想检索会话中的所有数据,可以使用 All
方法:
data := ctx.Request().Session().All()
检索数据子集
如果您想检索会话数据的子集,可以使用 Only
方法:
data := ctx.Request().Session().Only([]string{"username", "email"})
判断会话中是否存在某项
要判断会话中是否存在某项,可以使用 Has
方法。 如果该项存在且不为 nil
,Has
方法将返回 true
:
if ctx.Request().Session().Has("user") {
//
}
要判断某项是否存在,即使它是 nil
,您可以使用 Exists
方法:
if ctx.Request().Session().Exists("user") {
//
}
要确定会话中是否不存在某个项目,你可以使用 Missing
方法:
if ctx.Request().Session().Missing("user") {
//
}
存储数据
你可以使用 Put
方法在会话中存储数据:
ctx.Request().Session().Put("key", "value")
获取和删除数据
如果你想从会话中获取一个项目然后删除它,你可以使用 Pull
方法:
value := ctx.Request().Session().Pull("key")
删除数据
Forget
方法可用于从会话中删除一条数据。 如果你想要从会话中删除所有数据, 可以使用 Flush
方法:
ctx.Request().Session().Forget("username", "email")
ctx.Request().Session().Flush()
重新生成会话 ID
重新生成会话 ID 通常是为了防止恶意用户利用会话固定攻击 来攻击你的应用程序。 你可以使用 Regenerate
方法重新生成会话 ID:
ctx.Request().Session().Regenerate()
如果你想重新生成会话 ID 并忘记会话中的所有数据,可以使用 Invalidate
方法:
ctx.Request().Session().Invalidate()
然后,你需要将新会话保存到 cookie 中:
ctx.Response().Cookie(http.Cookie{
Name: ctx.Request().Session().GetName(),
Value: ctx.Request().Session().GetID(),
MaxAge: facades.Config().GetInt("session.lifetime") * 60,
Path: facades.Config().GetString("session.path"),
Domain: facades.Config().GetString("session.domain"),
Secure: facades.Config().GetBool("session.secure"),
HttpOnly: facades.Config().GetBool("session.http_only"),
SameSite: facades.Config().GetString("session.same_site"),
})
闪存数据
闪存数据是只在后续 HTTP 请求期间可用,然后将被删除的会话数据。 闪存数据对于存储临时消息(如状态消息)非常有用。 您可以使用 Flash
方法在会话中存储闪存数据:
ctx.Request().Session().Flash("status", "Task was successful!")
如果您希望闪存数据在额外的请求中保持可用,可以使用 Reflash
方法:
ctx.Request().Session().Reflash()
如果您想在额外的请求中保留特定的闪存数据,可以使用 Keep
方法:
ctx.Request().Session().Keep("status", "username")
如果您想立即使用特定数据,可以使用 Now
方法:
ctx.Request().Session().Now("status", "Task was successful!")
与会话管理器交互
构建自定义会话
使用 Session
门面来构建自定义会话。 Session
门面提供了 BuildSession
方法,该方法接受一个驱动实例和一个可选的会话 ID(如果您想指定自定义会话 ID):
import "github.com/goravel/framework/facades"
session := facades.Session().BuildSession(driver, "sessionID")
添加自定义会话驱动
实现驱动
要实现自定义会话驱动程序,驱动程序必须实现 contracts/session/driver
接口。
// Driver 是 Session 处理程序的接口。
type Driver interface {
// Close 关闭会话处理程序。
Close() error
// Destroy 销毁具有给定 ID 的会话。
Destroy(id string) error
// Gc 对具有给定最大生存期的会话处理程序执行垃圾回收。
Gc(maxLifetime int) error
// Open 使用给定的路径和名称打开会话。
Open(path string, name string) error
// Read 读取与给定 ID 关联的会话数据。
Read(id string) (string, error)
// Write 写入与给定 ID 关联的会话数据。
Write(id string, data string) error
}
注册驱动程序
实现驱动程序后,您需要在 Goravel 中注册它。 您可以使用 facades.Session
的 Extend
方法来实现这一点。 您应该在 app/providers/app_service_provider.go
的 boot
方法中调用 Extend
方法:
import "github.com/goravel/framework/contracts/session"
facades.Session().Extend("redis", func() session.Driver {
return &RedisDriver{}
})
一旦驱动程序注册完成,您可以通过在会话配置文件中将 driver
选项设置为 redis
,或者将 SESSION_DRIVER
环境变量设置为 redis
来使用它。
获取驱动程序实例
使用 Driver
方法从会话管理器中获取驱动程序实例。 它接受一个可选的驱动程序名称,如果未提供,则返回默认驱动程序实例:
driver, err := facades.Session().Driver("file")
开始一个新会话
session := facades.Session().BuildSession(driver)
session.Start()
保存会话数据
session := facades.Session().BuildSession(driver)
session.Start()
session.Save()
将会话附加到请求
session := facades.Session().BuildSession(driver)
session.Start()
ctx.Request().SetSession(session)
检查请求是否有会话
if ctx.Request().HasSession() {
//
}