Django 利用nginx+redis 实现单点登录(共享session的方法)

最近,在做一个项目,需要把以前写的django项目统一到一个新的django项目中,并保持所有系统的登录状态,即单点登录。搜了一圈,方法很多,但要在其中,选择最快速上线的确实不简单。又说用SSO系统,有的说用CAS认证,有的说用jwt机密token。最后,我选择了共享session。

    思路十分清晰,共享session就是把cookie存的session_id的session信息通过一个公共的媒介存储下来,所有系统统一读写。由于django有各种数据库引擎,可以借用其中一个,方便实现单点登录。

在3个Django 正常运行的情况下,我们需要安装nginx和redis服务。这里不展开说nginx和redis的安装。

(一)nginx服务配置(反向代理)

server {
    listen    10011; #监听的端口
    server_name   xxx.xxx.com;#域名名称(这里做了脱敏)
    #autoindex on;
    charset    utf-8;

    client_max_body_size 10M;

    location / {
            proxy_redirect off; #关闭强制重定向(如果需要设置http跳https可以在这里设置)
            uwsgi_pass 127.0.0.1:1234; #设置代理服务器和端口(这里使用了uwsgi服务)
            #proxy_pass http://192.168.1.123;#不用uwsgi 的socket设置也可以直接代理http服务
            include uwsgi_params;#uwsgi代理设置需要带上
            proxy_cookie_path / /; #设置代理的cookie路径
            fastcgi_buffer_size 64k;#如果返回数据过大需要设置代理的buffer大小
            fastcgi_buffers 32 32k;
            fastcgi_busy_buffers_size 128k;
            proxy_set_header Host $host;#设置代理的header配置
            proxy_set_header Referer $http_referer;
            proxy_set_header Cookie $http_cookie; 
            proxy_set_header X-Real-Ip $remote_addr;
            proxy_set_header X-Forwarded-For $remote_addr;
            #proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            add_header Access-Control-Allow-Origin $http_origin; #允许跨域
            add_header Access-Control-Allow-Methods *;
            add_header Access-Control-Max-Age 3600;
            add_header Access-Control-Allow-Credentials true;
            add_header Access-Control-Allow-Headers true;
            
            }
    }

反向代理设置后 如上配置,代理的路径为"/",则代理时只需要对应的ip或域名 以及端口,路径后的内容将自动代理。这时所有Django服务都设置再同一个nginx代理服务器下,即可完成一半的配置操作。

(二)Django setting配置

接下来配置Django的setting

有几个地方需要配置:

(1)SECRET_KEY

SECRET_KEY需要是每个Django服务都要相同,才能共享session。个人认为是Django的一个唯一加密串。配置如下:

加密字符串可以是任意字符串,但每个Django服务的该字符串要相同。

(2)redis缓存机制配置

一开始提到的DJango 缓存机制就是在setting的这里配置的

# redis配置
CACHES = {
     "default": {#设置数据库名称
         "BACKEND": "django_redis.cache.RedisCache",
         "LOCATION": "redis://ip:6379/15",#ip为脱敏信息,设置redis的数据库位置为15号数据库
         "OPTIONS": {
             "CLIENT_CLASS": "django_redis.client.DefaultClient",
             "CONNECTION_POOL_KWARGS": {"max_connections": 100},
             "PASSWORD": "密码"#密码为脱敏信息
         }
     },
    "session":{ #设置数据库名称
        "BACKEND": "django_redis.cache.RedisCache",
         "LOCATION": "redis://ip:6379/1",
         "OPTIONS": {
             "CLIENT_CLASS": "django_redis.client.DefaultClient",
             "CONNECTION_POOL_KWARGS": {"max_connections": 100},
             "PASSWORD": "密码"#密码为脱敏信息
         }
     },
 }

SESSION_ENGINE = 'django.contrib.sessions.backends.cache' #这里只用到缓存 没有用到数据库,其他机制可以按需配置
SESSION_CACHE_ALIAS = 'session' #指定选择的缓存数据库

SESSION_COOKIE_AGE = 60*5 #设置cookie的有效时长
SESSION_COOKIE_NAME = 'session' #设置相同的session再cookie中的名称,默认是session_id
SESSION_COOKIE_HTTPONLY=False #设置是否httponly
#SESSION_COOKIE_DOMAIN = '.domain.com' #设置cookie的作用域
# Application definition

(3)Django 中间件配置

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',#配置session的中间件
    'django.middleware.common.CommonMiddleware',
    #'django.middleware.csrf.CsrfViewMiddleware', #这里注释了csrf认证模块,怀疑可以不用关闭csrf,但未实际操作过
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

(三)实操排坑

(1)session冲突

配置完成后,出现某个Django登录后,再跳到另一个Django,前面的那个Django直接跳回登录页面。即两个Django的session发生冲突。

其他人的解决方法是:设置不同的sessionID在cookie中的key值或使用不同的域名。

但这就不能实现单点登录了。所以我排查了配置文件,发现原来有的Django服务设置了SSL,所以要统一所有django的SSL证书,不然就会出现上述的session冲突问题。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值