python解析laravel cookie

1,601 阅读3分钟

背景

最近在学习 fastapi,刚好有一个爬虫项目需要我开发。公司之前的技术栈是 php,线上的老项目都是 laravel 写的,laravel 的性能懂的都懂,实在是有点不忍直视,但是开发速度确实很快。

fastapi 算是 python 框架里比较好的,可以自动生成 swagger 文档,用起来也是非常方便。

laravel 的 cookie 解析起来还是有点复杂的,当然这也是 laravel 比较安全的一个保障。

现在要用 fastapi 跟 laravel 共存,为前端提供接口的话,有两种方案

  • laravel 做一层代理,通过了鉴权再调用一下 python 项目,相当于做了一层代理
  • 用 python 实现一套处理 laravel cookie 的解析方案

前面也说到 php 整体性能偏差,做一层代理的话性能消耗会更高,所以直接 pass 掉,选择自己实现一套解析。

技术详解

image.png

laravel使用了比较多的安全策略,这也是laravel性能较差的一些原因,每次cookie解析都要使用aes-256-cbc加密解密,cpu的消耗也是比较明显的。

搞清楚了解析流程就比较简单了,后续就是用python实现一套相同的流程

session 默认的序列化为 serialization,可以通过在配置文件 config/session.php 增加 'serialization' => "json" 设置序列化为 json 模式,方便跨语言解析,当然 serialization 方法也比较简单,如果无法更改为 json,也可以自己实现,或者使用第三方包。

开发

首先实现一个 aes-256-cbc 解密算法

def _unpad(s):
    return s[: -s[-1]]
    
    
def aes256cbc_decrypt(key, iv, ciphertext):
    # 解码密文
    key = base64.b64decode(key)
    iv = base64.b64decode(iv)
    ciphertext = base64.b64decode(ciphertext)

    # 创建AES解密器
    cipher = AES.new(key, AES.MODE_CBC, iv)

    # 解密密文
    decrypted_text = cipher.decrypt(ciphertext)

    # 去除填充
    decrypted_text = _unpad(decrypted_text)

    # 返回解密结果
    return decrypted_text.decode("utf-8")

实现一个 laravel cookie 解析方法

def laravel_decrypt(laravel_cookie) -> str:
    if not laravel_cookie or laravel_cookie == "":
        return ""
    laravel_config = Setting.Laravel
    # 测试
    session_obj = decode_cookie_str(laravel_cookie)

    iv = session_obj["iv"].encode()

    return aes256cbc_decrypt(laravel_config.key, iv, session_obj["value"])

新版 laravel 增加了一个 cookie key 的 hmac hash,用 | 分割开前面是 key 的 hash值,后面是 Session ID

  1. 获取到了 Session ID ,就可以获取到 session 中存储的具体值,如果值中存在 login_web_59ba36addc2b2f9401580f014c7f58ea4e30989d 的 key,说明用户已经登陆,此 key 的值即为用户 ID。
  2. 如果 Session ID 不存在,需要尝试从 cookie 中获取 remember_web_59ba36addc2b2f9401580f014c7f58ea4e30989d,如果存在,使用相同的解析方法解析开来,可以获取到用户 ID,remember_token,encryped_password 三个字,根据用户 ID 尝试从数据库获取用户信息,然后对比 remember_token 和 encryped_password 的值,如果相同,说明用户应该存在登陆态,刷新登陆态到 Session 中。

总结

以上就是 python 解析 laravel cookie 的大部分内容,后面就可以愉快地使用 python 做开发了,这套方案整体安全性还是比较高的,也可以看到 app_key 这个变量的巨大作用,千万不要泄露了。

更新

最近又用 golang 做了一下改写,性能更好,使用 golang 的同学可以参考:golang 解析 laravel cookie 以及 CloudWeGo hertz 框架实现