增加了讨论区的 SSO 登录

This commit is contained in:
virusdefender
2015-10-20 20:09:23 +08:00
parent da54a1245b
commit 17f1820955
6 changed files with 43 additions and 30 deletions

View File

@@ -58,3 +58,7 @@ class ResetPasswordSerializer(serializers.Serializer):
token = serializers.CharField(min_length=1, max_length=40) token = serializers.CharField(min_length=1, max_length=40)
password = serializers.CharField(min_length=6, max_length=30) password = serializers.CharField(min_length=6, max_length=30)
captcha = serializers.CharField(max_length=4, min_length=4) captcha = serializers.CharField(max_length=4, min_length=4)
class SSOSerializer(serializers.Serializer):
token = serializers.CharField(max_length=40)

View File

@@ -5,6 +5,7 @@ from django.contrib import auth
from django.shortcuts import render from django.shortcuts import render
from django.db.models import Q from django.db.models import Q
from django.conf import settings from django.conf import settings
from django.http import HttpResponseRedirect
from django.core.exceptions import MultipleObjectsReturned from django.core.exceptions import MultipleObjectsReturned
from django.utils.timezone import now from django.utils.timezone import now
@@ -20,7 +21,8 @@ from .models import User
from .serializers import (UserLoginSerializer, UsernameCheckSerializer, from .serializers import (UserLoginSerializer, UsernameCheckSerializer,
UserRegisterSerializer, UserChangePasswordSerializer, UserRegisterSerializer, UserChangePasswordSerializer,
EmailCheckSerializer, UserSerializer, EditUserSerializer, EmailCheckSerializer, UserSerializer, EditUserSerializer,
ApplyResetPasswordSerializer, ResetPasswordSerializer) ApplyResetPasswordSerializer, ResetPasswordSerializer,
SSOSerializer)
from .decorators import super_admin_required from .decorators import super_admin_required
@@ -287,12 +289,24 @@ def user_index_page(request, username):
return render(request, "oj/account/user_index.html") return render(request, "oj/account/user_index.html")
def auth_page(request): class SSOAPIView(APIView):
if not request.user.is_authenticated(): def post(self, request):
return render(request, "oj/account/oauth.html") serializer = SSOSerializer(data=request.data)
callback = request.GET.get("callback", None) if serializer.is_valid():
if not callback: try:
return error_page(request, u"参数错误") user = User.objects.get(auth_token=serializer.data["token"])
token = rand_str() return success_response({"username": user.username})
request.user.auth_token = token except User.DoesNotExist:
return render(request, "oj/account/oauth.html", {"callback": callback, "token": token}) return error_response(u"用户不存在")
else:
return serializer_invalid_response(serializer)
@login_required
def get(self, request):
callback = request.GET.get("callback", None)
if not callback or callback != settings.SSO["callback"]:
return error_page(request, u"参数错误")
token = rand_str()
request.user.auth_token = token
request.user.save()
return render(request, "oj/account/sso.html", {"redirect_url": callback + "?token=" + token, "callback": callback})

View File

@@ -11,18 +11,13 @@ DATABASES = {
}, },
# submission 的 name 和 engine 请勿修改,其他代码会用到 # submission 的 name 和 engine 请勿修改,其他代码会用到
'submission': { 'submission': {
'NAME': 'oj_submission', 'ENGINE': 'django.db.backends.sqlite3',
'ENGINE': 'django.db.backends.mysql', 'NAME': os.path.join(BASE_DIR, 'db1.sqlite3'),
'CONN_MAX_AGE': 0.1,
'HOST': "127.0.0.1",
'PORT': 3306,
'USER': 'root',
'PASSWORD': 'root',
} }
} }
REDIS_CACHE = { REDIS_CACHE = {
"host": "121.42.32.129", "host": "127.0.0.1",
"port": 6379, "port": 6379,
"db": 1 "db": 1
} }
@@ -37,3 +32,5 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, "static/src/"), BASE_DIR]
# 模板文件夹 # 模板文件夹
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/src/')] TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/src/')]
SSO = {"callback": "http://localhost:8765/login"}

View File

@@ -43,3 +43,5 @@ STATICFILES_DIRS = [os.path.join(BASE_DIR, "static/release/"), os.path.join(BASE
TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/release/')] TEMPLATE_DIRS = [os.path.join(BASE_DIR, 'template/release/')]
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
SSO = {"callback": "https://discuss.acmer.site/login"}

View File

@@ -6,7 +6,7 @@ from django.views.generic import TemplateView
from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView, from account.views import (UserLoginAPIView, UsernameCheckAPIView, UserRegisterAPIView,
UserChangePasswordAPIView, EmailCheckAPIView, UserChangePasswordAPIView, EmailCheckAPIView,
UserAdminAPIView, UserInfoAPIView, UserAdminAPIView, UserInfoAPIView,
ApplyResetPasswordAPIView) ApplyResetPasswordAPIView, SSOAPIView)
from announcement.views import AnnouncementAdminAPIView from announcement.views import AnnouncementAdminAPIView
@@ -127,7 +127,7 @@ urlpatterns = [
url(r'^account/settings/$', TemplateView.as_view(template_name="oj/account/settings.html"), name="account_setting_page"), url(r'^account/settings/$', TemplateView.as_view(template_name="oj/account/settings.html"), name="account_setting_page"),
url(r'^account/settings/avatar/$', TemplateView.as_view(template_name="oj/account/avatar.html"), name="avatar_settings_page"), url(r'^account/settings/avatar/$', TemplateView.as_view(template_name="oj/account/avatar.html"), name="avatar_settings_page"),
url(r'^account/auth/$', "account.views.auth_page", name="auth_login_page"), url(r'^account/sso/$', SSOAPIView.as_view(), name="sso_api"),
] ]

View File

@@ -5,17 +5,13 @@
{% block body %} {% block body %}
<div class="container main"> <div class="container main">
<div class="text-center"> <div class="text-center">
{% if request.user.is_authenticated %} <p>3秒钟后将使用账号{{ request.user.username }}登录<span id="link">{{ callback }}</span></p>
<p>3秒钟后将跳转到<span id="link">{{ callback }}</span></p> <button class="btn btn-warning" onclick="location.href='/'">取消登录</button>
<button class="btn btn-success" onclick="location.href='/login/'">更换账号</button>
<script>setTimeout(function(){ <script>setTimeout(function(){
window.location.href = "{{ callback }}?token={{ token }}"}, window.location.href = "{{ redirect_url }}"},
3000); 3000);
</script> </script>
{% else %}
<script>window.location.href = "/login/";</script>
{% endif %}
</div> </div>
</div> </div>
{% endblock %} {% endblock %}