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

您所在的位置:网站首页 如何实现单点唤醒 Django 利用nginx+redis 实现单点登录(共享session的方法)

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

2023-08-20 04:29| 来源: 网络整理| 查看: 265

最近,在做一个项目,需要把以前写的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冲突问题。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3