Django 和 PHP Yii 框架共用Session日记

django redis session Yii1.0 2017年04月01日 星期六

业务的多样化促使可能由多种语言不同的框架实现。目前的项目中由两部分框架进行完成PHP Yii1.0 和 Python Django1.8,需要实现两边服务器Session共用,即是用户在一端登录可以在任意端实现已登录状态。

在服务器端由于http是无状态请求,用于记录用户的登录状态通用的则是session机制,原理则是 登录的时候服务器端生成一个sessionid 用于唯一表示一条session数据记录,会记录该用户信息的标识如user_id,客户端在每次请求的时候cookie中带上该值,这样就实现了客户端和服务器端之间的会话。考虑性能存储session数据本次选择了redis,下面主要介绍下Django Redis Session方面的实现。

本次借鉴了开源库django-redis-sessions,该库对Redis存储提供很方便的API,只需在settings文件中进行简单的配置即可:

# Redis Session 配置
SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = REDIS_HOST
SESSION_REDIS_PORT = REDIS_PORT
SESSION_REDIS_DB = 0
# 为了区分标识,所有在redis中的session增加一个固定的前缀
SESSION_REDIS_PREFIX = 'REDIS_SESSION'

为了对接PHP的session机制,则需要改变对应的SessionStore encode/decode方法,在PHP中session的数据则是通过serialize方法进行序列化存储的,可以借助开源库phpserialize对应的loads/dumps方法来进行加解密。

Django中的登录、登出:

from django.contrib.auth import login, logout

# 登录
login(request, user)

# 登出
logout(request)

Django中请求对象request设置session和user属性都是通过middleware实现的:

1. 设置 request.session <==> django.contrib.sessions.middleware.SessionMiddleware

在这个中间件过程中,通过settings.SESSION_COOKIE_NAME来获取前后端统一的cookie session name,从而获取当前请求的session_key 则就是上述的session_id ,会话的唯一标识。在process_response中,通过判断session是否修改去进行保存到数据库,同时通过request.set_cookie进行对cookie的设置。

2. 设置 request.user <==> django.contrib.auth.middleware.AuthenticationMiddleware

在这个中间件过程中,通过auth.get_user进行获取当前登录用户对象,原理则是通过session中保存的user_id进行查找。

在此过程中,总结session多服务端共用的几点:

1. 理解session的实现原理。

2. 设置cookie session_name 相同。

3. 对于存储于数据库如redis的值,加解密统一。

4. 数据中保存的用户标识统一。

就酱,完成了,^ . ^ 。