1.安装django-simple-sso:
pip install django-simple-sso
2.Server端配置完成simple_sso.sso_server应用的注册后,将对应的数据表迁移到数据库中python manage.py migrate
。在数据表sso_server_consumer中添加一条密钥对,随便找两个字符串就像Django中SECRET_KEY差不多,这里我就用简单的字符串代替。如果在django交互界面去创建一条记录:
# 进入django shell
python mange.py shell
# django shell
from simple_sso.sso_server.models import Consumer
Consumer.objects.create(public_key='public', private_key='private', name='basics')
3.配置Server端:
# 注册 simple_sso.sso_server
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account',
'simple_sso.sso_server'
]
# 项目同名文件夹下url.py
from django.contrib import admin
from django.urls import path, include
from simple_sso.sso_server.server import Server
from account.views import index
test_server = Server(auth_view_name='account:login')
urlpatterns = [
path('', index),
path('admin/', admin.site.urls),
path('account/', include(('account.urls', 'account'), namespace='account')),
path('server/', include(test_server.get_urls())),
]
# account应用下url.py
from django.urls import path
from account import views
urlpatterns = [
path('login/', views.SSOLoginView.as_view(), name='login'),
]
# account/login/ 视图类
class SSOLoginView(LoginView):
template_name = 'account/login.html'
{% extends 'base.html' %}
{% block title %}
<title>登陆</title>
{% endblock %}
{% block body %}
<div class="app">
<form action="{% url "account:login" %}" method="post">
{% csrf_token %}
<div class="row extend-margin">
<div class="col-xs-12">
<div class="form-account">
<div class="input-1">
<input type="text" class="form-control" name="username" placeholder="请输入邮箱">
</div>
<div class="input-2"></div>
<div class="input-3">
<input type="password" class="form-control" name="password" placeholder="请输入密码">
</div>
</div>
</div>
</div>
<input type="hidden" name="next" value="{{ next }}">
<div class="row extend-margin">
<div class="col-xs-12">
<div class="extend-operate">
<label for="remember"><input type="checkbox" id="remember">记住我</label>
<a href="#">忘记密码</a>
</div>
</div>
</div>
<div class="row extend-margin">
<div class="col-xs-12">
<div class="account-submit">
<input type="submit" class="form-control" value="登录">
</div>
</div>
</div>
</form>
</div>
{% endblock %}
4.配置Client端:
# 注册 simple_sso.sso_client 应用
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account',
'simple_sso.sso_client',
]
# 需要用到的一些常量
# django_simple_sso
###########################################
# SSO
###########################################
SSO_SERVER = 'http://a.cn:8008/server/'
SSO_PUBLIC_KEY = 'public'
SSO_PRIVATE_KEY = 'private'
SSO_CLIENT = 'http://a.cn:8009/'
# 项目同名ulr.py
from django.contrib import admin
from django.shortcuts import redirect
from django.urls import path, include
from simple_sso.sso_client.client import Client
from basics_client import settings
test_client = Client(settings.SSO_SERVER, settings.SSO_PUBLIC_KEY, settings.SSO_PRIVATE_KEY)
urlpatterns = [
path('', lambda request: redirect('/client/' if not request.user.is_authenticated else 'index/', permanent=False)),
path('admin/', admin.site.urls),
path('client/', include(test_client.get_urls())),
path('index/', include('account.urls')),
]
5.晃晃悠悠做了一天的流程图,掌握这个流程自己写SSO也可以了:
6.client端和server端的验证加密方式:
# pip install itsdangerous
from itsdangerous import TimedSerializer
# Client、Server实例化序列化器
signer = TimedSerializer('private')
s2 = signer.dumps({'target': 'test'}) # '{"target": "test"}.Xzd5YA.qfFLTfpLxh3z8XUOYe8YCZ1ZDZs'
# max_age=5从dumps到loads超过5秒报signer expire
s = signer.loads(s2, max_age=5) # {'target': 'test'}
7.Server端生成Token:
# 字符串大小写+数字
KEY_CHARACTERS = string.ascii_letters + string.digits
# 创建token
def default_gen_secret_key(length=40):
return ''.join([random.choice(KEY_CHARACTERS) for _ in range(length)])
# Token model
class Token(models.Model):
consumer = models.ForeignKey(
Consumer,
related_name='tokens',
on_delete=models.CASCADE,
)
request_token = models.CharField(
unique=True, max_length=64,
default=TokenSecretKeyGenerator('request_token')
)
access_token = models.CharField(
unique=True, max_length=64,
default=TokenSecretKeyGenerator('access_token')
)
timestamp = models.DateTimeField(default=timezone.now)
redirect_to = models.CharField(max_length=255)
user = models.ForeignKey(
getattr(settings, 'AUTH_USER_MODEL', 'auth.User'),
null=True,
on_delete=models.CASCADE,
)
def refresh(self):
self.timestamp = timezone.now()
self.save()
总结来说,如果你想要做一个SSO先上码云拉一个client和server的案例跑通了,改改就能用的,之后我会分析我们项目里面的接入SSO验证的ModelBackend后端校验类。