golang 解析 laravel cookie 以及 CloudWeGo hertz 框架实现

258 阅读3分钟

背景

上一篇文章 python 解析 laravel cookie 讲解了解析 laravel cookie 的基本原理,以及 python 语言解析的简单实现。效果还是可以的,我自己的项目已经用上了,实现了与 laravel 一起工作的 fastapi 项目。

python 虽好,性能却始终不理想,本文将使用 golang 语言来实现解析 laravel cookie,以及基于 cloudwego 社区的 hertz 框架中间件的一个简单实现,项目地址 hertz-laravel

实现

主要分为三个部分

  1. 获取 cookie 并解析出相应的 sessionId 或者 remember_web
  2. 根据 sessionId 从相应存储中获取数据,解析数据获取 user_id
  3. 根据 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)
}
配置解释
appKeylaravel 的 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 带来的性能提升

相关项目链接