重庆网站建设咨询会计培训机构
统一的用户认证体系是后台系统的基础模块,直接关系到系统安全性与用户体验。结合 Django、DRF 与 JWT,能够快速实现灵活且高效的身份认证与接口授权机制。
本文解析 dvadmin/system/views/login.py
模块的实现细节,涵盖验证码生成、登录校验、登出接口等核心功能,分析其在认证流程中如何组织数据处理、权限校验与异常管理。
文章目录
- login.py
- 项目源码解析
- 应用案例
- 总结
login.py
本系统基于 Django 开发,结合 Restful API 实现后台统一认证与权限管理。dvadmin/system/views/login.py
文件负责处理用户认证相关接口,包括登录、登出、验证码获取等功能。该模块是系统用户身份验证的入口,通过安全校验机制保障系统账户安全。模块设计兼顾常规用户名密码登录和验证码认证登录需求,并在成功登录后生成 Token 令牌用于后续接口授权访问。
项目特点 | 描述 |
---|---|
技术栈 | Django + DRF + JWT |
功能定位 | 提供用户登录、验证码获取、退出登录等接口 |
安全机制 | 密码加密验证,登录失败处理,支持验证码防止暴力破解 |
响应方式 | 登录成功返回 JWT Token,后续接口调用需携带 Token |
dvadmin/system/views/login.py
文件定义了用户认证流程相关接口。内部通过继承自 APIView
或自定义 CustomModelViewSet
,组织了登录验证、验证码生成、用户登出等功能。登录流程支持根据用户名密码校验账号信息,验证码接口生成随机图形验证码用于前端展示,登出接口清除 Token 或 Session 信息。模块内统一使用标准返回格式,提高前后端交互的一致性和易用性,保证接口的安全性和扩展性。
模块职责 | 说明 |
---|---|
用户登录验证 | 接收用户名和密码,校验成功后返回认证 Token |
验证码生成与校验 | 提供图形验证码接口,防止自动化程序攻击 |
用户登出 | 处理用户退出逻辑,清理 Token 或 Session |
登录状态反馈 | 返回登录状态、用户基本信息、权限列表 |
异常处理 | 登录失败、验证码错误等情况统一处理,保障接口稳定性 |
在任何需要用户认证和权限校验的管理系统、平台系统中,dvadmin/system/views/login.py
提供了必要的认证能力。通过统一的 Token 登录体系,实现用户身份确认与后续接口访问控制,保证了系统资源的安全访问。开发人员可以基于该模块快速搭建完善的用户认证体系,同时支持扩展多种登录方式如手机号、邮箱、验证码等。
使用场景 | 说明 |
---|---|
后台管理系统登录 | 用户输入账号密码,系统校验成功后生成 Token |
手机验证码登录 | 提供验证码接口辅助验证,增强登录安全性 |
用户登出功能 | 支持前端主动调用登出接口,清除登录态 |
图形验证码防止刷库攻击 | 登录前先请求验证码接口,防止自动化脚本攻击 |
接口权限控制体系搭建 | 登录后统一使用 Token 授权管理系统所有接口访问 |
项目源码解析
验证码生成接口
CaptchaView
负责生成图片验证码,并将验证码图片以 base64 编码形式返回。它依赖 Django 的 CaptchaStore
管理验证码记录,借助 dispatch
调用系统配置开关,决定是否启用验证码功能。这一模块主要与登录认证模块协作,提升系统安全性,同时保持较好的可控性和扩展性。
class CaptchaView(APIView):authentication_classes = []permission_classes = []def get(self, request):data = {}if dispatch.get_system_config_values("base.captcha_state"):hashkey = CaptchaStore.generate_key()id = CaptchaStore.objects.filter(hashkey=hashkey).first().idimgage = captcha_image(request, hashkey)image_base = base64.b64encode(imgage.content)data = {"key": id,"image_base": "data:image/png;base64," + image_base.decode("utf-8"),}return DetailResponse(data=data)
登录数据处理序列化器
LoginSerializer
继承自 TokenObtainPairSerializer
,用于重写 JWT 登录流程。它增加了验证码校验逻辑,支持手机号、邮箱或用户名登录,处理登录失败次数限制,并根据系统配置动态启用或禁用验证码校验。该模块与 Users
模型、系统配置模块、验证码模块密切协作,是登录验证体系的核心部分。
class LoginSerializer(TokenObtainPairSerializer):captcha = serializers.CharField(max_length=6, required=False, allow_null=True, allow_blank=True)def validate(self, attrs):captcha = self.initial_data.get("captcha", None)if dispatch.get_system_config_values("base.captcha_state"):if captcha is None:raise CustomValidationError("验证码不能为空")self.image_code = CaptchaStore.objects.filter(id=self.initial_data["captchaKey"]).first()five_minute_ago = datetime.now() - timedelta(minutes=5)if self.image_code and five_minute_ago > self.image_code.expiration:self.image_code and self.image_code.delete()raise CustomValidationError("验证码过期")else:if self.image_code and (self.image_code.response == captcha or self.image_code.challenge == captcha):self.image_code and self.image_code.delete()else:self.image_code and self.image_code.delete()raise CustomValidationError("图片验证码错误")try:user = Users.objects.get(Q(username=attrs['username']) | Q(email=attrs['username']) | Q(mobile=attrs['username']))except Users.DoesNotExist:raise CustomValidationError("您登录的账号不存在")except Users.MultipleObjectsReturned:raise CustomValidationError("您登录的账号存在多个,请联系管理员检查登录账号唯一性")if not user.is_active:raise CustomValidationError("账号已被锁定,联系管理员解锁")try:attrs['username'] = user.usernamedata = super().validate(attrs)data.update({"username": self.user.username,"name": self.user.name,"userId": self.user.id,"avatar": self.user.avatar,"user_type": self.user.user_type,"pwd_change_count": self.user.pwd_change_count,})dept = getattr(self.user, 'dept', None)if dept:data['dept_info'] = {'dept_id': dept.id,'dept_name': dept.name,}role = getattr(self.user, 'role', None)if role:data['role_info'] = role.values('id', 'name', 'key')request = self.context.get("request")request.user = self.usersave_login_log(request=request)user.login_error_count = 0user.save()return {"code": 2000, "msg": "请求成功", "data": data}except Exception:user.login_error_count += 1if user.login_error_count >= 5:user.is_active = Falseuser.save()raise CustomValidationError("账号已被锁定,联系管理员解锁")user.save()count = 5 - user.login_error_countraise CustomValidationError(f"账号/密码错误;重试{count}次后将被锁定~")
登录接口控制器
LoginView
继承自 TokenObtainPairView
,指定使用自定义的 LoginSerializer
处理登录流程。它去除了默认认证权限设置,允许未登录状态下访问,作为整个用户认证入口,与 JWT 认证模块配合使用。
class LoginView(TokenObtainPairView):serializer_class = LoginSerializerpermission_classes = []
特殊场景登录序列化器
LoginTokenSerializer
用于跳过验证码校验直接登录的场景(如 API 测试环境),根据系统配置开关控制是否允许访问,适用于特定部署模式下的内部系统对接或测试环境,保证生产环境安全性。
class LoginTokenSerializer(TokenObtainPairSerializer):def validate(self, attrs):if not getattr(settings, "LOGIN_NO_CAPTCHA_AUTH", False):return {"code": 4000, "msg": "该接口暂未开通!", "data": None}data = super().validate(attrs)data.update({"name": self.user.name,"userId": self.user.id,})return {"code": 2000, "msg": "请求成功", "data": data}
特殊场景登录接口
LoginTokenView
继承自 TokenObtainPairView
,使用 LoginTokenSerializer
作为数据处理器,提供一个跳过验证码验证的快速登录通道,与标准登录流程并行但互不干扰。
class LoginTokenView(TokenObtainPairView):serializer_class = LoginTokenSerializerpermission_classes = []
注销接口
LogoutView
提供一个简单的注销接口,返回固定格式的成功响应。因为系统使用 JWT 认证,注销操作不涉及服务器端状态清除,属于前端逻辑辅助接口。
class LogoutView(APIView):def post(self, request):return DetailResponse(msg="注销成功")
接口文档登录表单序列化器
ApiLoginSerializer
用于接口文档环境下登录时的参数验证,仅接收用户名和密码两个字段,与标准用户模型关联。
class ApiLoginSerializer(CustomModelSerializer):username = serializers.CharField()password = serializers.CharField()class Meta:model = Usersfields = ["username", "password"]
接口文档登录接口
ApiLogin
提供给 Swagger 等接口文档系统使用的登录接口。它通过 Django 原生 auth.authenticate
方法校验用户身份,成功后调用 login
完成登录状态注册,失败则返回标准错误响应。适合接口测试时使用,不参与正式生产登录流程。
class ApiLogin(APIView):serializer_class = ApiLoginSerializerauthentication_classes = []permission_classes = []def post(self, request):username = request.data.get("username")password = request.data.get("password")user_obj = auth.authenticate(request,username=username,password=hashlib.md5(password.encode(encoding="UTF-8")).hexdigest(),)if user_obj:login(request, user_obj)return redirect("/")else:return ErrorResponse(msg="账号/密码错误")
应用案例
统一认证接口在后台系统中的登录安全实践
后台管理系统的入口安全直接影响整个系统的稳定性与数据安全。为满足多端统一认证、灵活登录方式、安全防护控制等需求,系统基于 Django REST framework 与 JWT 实现了一个支持账号、邮箱、手机号登录的统一认证服务,并结合验证码防爆破、失败次数限制与用户锁定机制,构建了安全可控的登录体系。
# 登录接口入口
class LoginView(TokenObtainPairView):serializer_class = LoginSerializerpermission_classes = []
在前端登录页面,用户提交账号、密码与验证码,后端由 LoginSerializer
进行处理:
# 登录请求数据格式
{"username": "admin@domain.com","password": "abc123456","captcha": "M7df9","captchaKey": "3f41e03f-ca49-4efb-b16a-02e1459f6d58"
}
后端认证流程:
该流程通过系统配置中心控制登录校验逻辑,支持灵活启停验证码机制。验证码信息存储于 CaptchaStore
表中,前端通过接口动态加载 base64 图片展示。后台登录失败记录逻辑通过 login_error_count
累计,达到阈值自动将 is_active
置为 False
,提升系统防护能力。
# 验证码校验逻辑片段
if self.image_code and (self.image_code.response == captcha or self.image_code.challenge == captcha):self.image_code.delete()
else:self.image_code.delete()raise CustomValidationError("图片验证码错误")
用户锁定机制
为防止爆破攻击,系统在每次登录失败后累加 login_error_count
,并在达到设定阈值(如 5 次)后自动禁用用户:
if user.login_error_count >= 5:user.is_active = Falseuser.save()raise CustomValidationError("账号已被锁定,联系管理员解锁")
该机制避免了传统无限尝试密码方式引发的系统风险,管理员可在用户管理中解锁账户。
登录成功返回内容
登录成功后,系统返回标准化响应内容,包含用户基本信息、角色、部门、权限结构、头像等字段,便于前端初始化权限菜单、个人信息及头像展示:
{"code": 2000,"msg": "请求成功","data": {"access": "eyJ0eXAiOiJKV1QiLCJh...","refresh": "eyJ0eXAiOiJKV1QiLCJh...","username": "admin","name": "系统管理员","userId": 1,"avatar": "/media/avatar.jpg","dept_info": {"dept_id": 2,"dept_name": "技术部"},"role_info": [{"id": 1,"name": "超级管理员","key": "admin"}]}
}
此后所有请求需在请求头中附带 Authorization: JWT <access token>
,以完成接口授权访问。
如需退出登录,前端调用:
POST /api/system/logout/
后端执行 LogoutView.post()
方法,返回固定成功响应,无需服务端状态管理。
开发测试时,若不启用验证码,可启用 LoginTokenView
进行免验证码登录,适用于接口调试环境:
POST /api/system/login/token/{"username": "test","password": "123456"
}
该模块还提供 ApiLogin
接口支持 Swagger 文档中的表单登录,便于在接口调试页面中快速完成认证状态注册,辅助开发联调阶段的调试操作。整套机制支持标准认证接口、扩展验证流程、自定义身份校验与登录日志追踪,是企业级后台系统中身份认证体系的核心组件。
总结
模块通过图形验证码提升登录安全性,基于 JWT 实现无状态认证,使用自定义序列化器灵活扩展登录校验规则。接口权限清晰分层,登录、登出、验证码请求各自独立,避免逻辑混杂,保障系统整体的可维护性与扩展性。
验证码验证逻辑与登录逻辑强耦合,复用性受限;多处异常捕获处理繁杂,可提取统一错误处理模块。登录失败锁定机制未异步处理,可能增加数据库负载。未来可进一步分离验证码服务与认证服务,提升模块解耦性与系统性能。