单点登录
单点登录 Single Sign On (简称 SSO),
是指在多系统应用群中登录一个系统,
便可在其他所有系统中得到授权而无需再次登录,
其中包括 单点登录 与 单点注销 两部分。
单用户登录
惭愧地说, 本篇文章和单点登录的功能并没有任何关系, 而是我将单点登录的概念和单用户登录的概念混淆了, 我的认为是:~~单点登录是某用户同一时间段内仅可以有一个在线状态, 符合某时间段上只有一个在线点。~~这是错误的, 但是我也没有找到所谓 单用户登录 的术语, 描述内容为:
同一时间段内, 某用户只允许一个在线状态的数字凭证。
直白一点即是 在 M 用户已登录在线的情况下, 同时继续登录 M 用户, 将会将上一次的登录状态强制挤出至下线 的行为。
实现
在使用 django-restframework 框架的时候,
用户注销和登录的功能代码请参考 demo 示例,
其中登出标识是修改用户表的 user_secret 字段标识,
那么:登录成功前修改了标识字段再登录即可实现该需求。是的,
此时查阅 JSONWebTokenSerializer 源码:
class JSONWebTokenSerializer(Serializer):
def validate(self, attrs):
...
这是用于用户认证的逻辑方法函数,
在返回用户 token 凭证前使用登出的方式修改状态,
最后我们的代码为:
#!/usr/bin/env python
# _*_ Coding: UTF-8 _*_
from rest_framework import serliazers
class UserJSONWebTokenSerializer(serializers.JSONWebTokenSerializer):
def validate(self, attrs):
credentials = {
self.username_field: attrs.get(self.username_field),
'password': attrs.get('password')
}
if all(credentials.values()):
user = authenticate(**credentials)
if user:
if not user.is_active:
msg = _('User account is disabled.')
raise serializers.ValidationError(msg)
# 修改用户认证的凭证字段
import uuid
user.user_secret = uuid.uuid4()
user.save()
payload = jwt_payload_handler(user)
return {
'token': jwt_encode_handler(payload),
'username': user
}
else:
msg = _('Unable to log in with provided credentials.')
raise serializers.ValidationError(msg)
else:
msg = _('Must include "{username_field}" and "password".')
msg = msg.format(username_field=self.username_field)
raise serializers.ValidationError(msg)
最后将重写的 UserJSONWebTokenSerializer 类注册到登录的 serializer_class 属性上就能实现了本篇文章的需求内容。
七月初一,立秋的第 13 天,三天后处暑,六天后七夕,有情人终成眷属~