关于在 django-restframework 中使用单用户登录

2,316 阅读2分钟

MedusaSorcerer的博客


单点登录

单点登录 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 天,三天后处暑,六天后七夕,有情人终成眷属~