背景
上一篇文章 python 解析 laravel cookie 讲解了解析 laravel cookie 的基本原理,以及 python 语言解析的简单实现。效果还是可以的,我自己的项目已经用上了,实现了与 laravel 一起工作的 fastapi 项目。
python 虽好,性能却始终不理想,本文将使用 golang 语言来实现解析 laravel cookie,以及基于 cloudwego 社区的 hertz 框架中间件的一个简单实现,项目地址 hertz-laravel
实现
主要分为三个部分
- 获取 cookie 并解析出相应的 sessionId 或者 remember_web
- 根据 sessionId 从相应存储中获取数据,解析数据获取 user_id
- 根据 remember_web 从数据库获取用户信息,以及对比两个信息是否一致
配置项
type authConfig struct {
appKey []byte
sessionCookieName string
rememberCookieName string
ignorePaths []string
disableEncryptCookies bool
exceptEncryptCookies []string
db *gorm.DB
tableName string
redisClient redis.UniversalClient
serialization serialization
cachePrefix string
UnAuthHandler func(ctx context.Context, c *app.RequestContext)
}
| 配置 | 解释 |
|---|---|
| appKey | laravel 的 appKey |
| sessionCookieName | 存放加密 sessionId 的 cookie 名称 |
| rememberCookieName | 存放加密 remember_web 的 cookie 名称 |
| ignorePaths | 不需要认证的请求路径 |
| disableEncryptCookies | 不需要加密 cookie,老版本 laravel 默认 |
| exceptEncryptCookies | 不需要加密的 cookie 名称 |
| db | 查询用户要用到的 gorm.DB |
| tableName | 用户表名称 |
| redisClient | 查询 session 信息的 redis 客户端 |
| serialization | 可选 php 或者 json,默认为 php |
| cachePrefix | 缓存前缀 |
| UnAuthHandler | 未认证处理方法 |
默认配置项
func defaultAuthConfig() *authConfig {
return &authConfig{
sessionCookieName: "laravel_session",
rememberCookieName: "remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d",
ignorePaths: []string{"/login", "/api/login"},
serialization: PhpSerialize,
tableName: "users",
}
}
获取 cookie 并解析
从请求头中获取到 cookie,使用 aes-cbc-256 解析 cookie 名称获取到 sessionId,新版本的 laravel 默认开启了 cookie 名称加密,获取到的数据包括一个 hmac sha256 的加密的 cookie 名称和一个 sessionId。同样步骤可以获取到 remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d。
根据 sessionId 从相应存储中获取数据
项目当前仅实现了从 redis 中获取 session 信息
由于 laravel cache 层存储的时候已经做了一次 php 序列化,所以从 redis 取出需要两次反序列化,第一次一定是 php 序列化,第二次根据配置,可以是 php 序列化,或者 json 序列化
根据 remember_web 从数据库获取用户信息,以及对比两个信息是否一致
laravel session 默认有效期是两个小时,如果登陆的时候选择了记住登陆状态,laravel 会生成一个 remember_web 开头的 cookie,同时在表里记 remember_token 字段,加密的 cookie 里面存储了用户 id、加密后的密码,表里的 remember_token。
验证的时候需要对比 cookie 中存储的 user_id, hashed_password, remember_token 字段是否一致,如果用户再次登陆改变了 remember_token,或者修改密码,会导致 remember_web 信息失效,触发掉线。
效果
实现了 laravel 登陆态解析之后,就可以使用 hertz 框架共享 laravel 的登陆状态,可以使用 hertz 开发新的功能而不会影响到旧的 php 项目,也可以使用此中间件构建一个小型的网关代理,后面可以使用各种语言开发新功能,享受 golang 带来的性能提升