使用 Python 全栈实现桌面图形程序的用户 Mac 地址绑定
在上一篇文档,我们介绍了使用 Python 的 PyQt5 框架构建一个支持用户登录的桌面图形程序,然后使用 Django 框架构建了一个用户认证的后端服务,使得 使用 PyQt5 写的用户登录程序可以通过这个后端服务进行用户的认证,只有认证通过,才会显示程序的主界面。
除了简单的用户登录认证,还有一些桌面程序需要绑定设备的 Mac 地址,以限制用户的使用。
当然,这种限制是有破解方法的,这里暂且不表。
我们接下来就在上一篇文章中所构建的项目中进行扩展,使其支持基于用户的 Mac 地址绑定和验证。
自定义一个用户模型
在之前的项目里面,我们直接使用了 Django 提供的用户认证模型,但是这个用户认证模型是不方便扩展的。现在我们在 Django 项目里面通过继承 AbstractUser 来自定义一个用户模型,在其中添加 Mac 地址相关的数据表字段。
d 如果你在使用上一篇文章的项目源码进行测试,那么请先删除 db.sqlite3 文件和 app_auth目录下的 migrations 文件夹
在 /qt_login_backend/app_auth/models.py 文件中,输入如下代码:
# coding:utf-8 # @作者:州的先生 # @博客:zmister.com # @公众号:zmister2016 from django.db import models from django.contrib.auth.models import AbstractUser # Create your models here. class User(AbstractUser): mac_status = models.BooleanField(verbose_name="Mac地址状态",default=True) mac_address = models.TextField(verbose_name="用户Mac地址",blank=True,null=True) def __str__(self): return self.username class Meta: verbose_name = '用户表' verbose_name_plural = verbose_name
然后执行数据模型迁移命令:
python manage.py makemigrations app_auth python manage.py migrate
在 /qt_login_backend/qt_login_backend/settings.py 文件中,添加如下代码以指定用户认证的模型:
AUTH_USER_MODEL = 'app_admin.User'
创建超级用户:
接着,在 /qt_login_backend/app_auth/admin.py 文件中将我们定义的 User 模型添加到 Django 的管理后台:
# coding:utf-8 # @作者:州的先生 # @博客:zmister.com # @公众号:zmister2016 from django.contrib import admin from app_auth.models import User # Register your models here. class UserAdmin(admin.ModelAdmin): list_display = ['username','mac_status','mac_address'] admin.site.register(User,UserAdmin)
我们进入到后台页面,可以看到刚刚定义的 User 模型已经添加到了管理页面中:
用户列表中显示了我们自定义的 Mac启用状态字段和 Mac地址字段:
编写Mac验证逻辑
我们对之前的视图函数 auth 进行一下修改,在 /qt_login_backend/app_auth/views.py 文件中:
@csrf_exempt def auth(request): if request.method == 'POST': username = request.POST.get('username','') password = request.POST.get('password','') mac_address = request.POST.get('mac_address','') if username != '' and password != '': user = authenticate(username=username, password=password) if user is not None: if user.is_active and user.mac_status is False: login(request, user) return JsonResponse({'status':True}) elif user.is_active and user.mac_status: if user.mac_address == mac_address: login(request, user) return JsonResponse({'status': True}) else: errormsg = '用户禁止在此设备登录!' return JsonResponse({'status': False, 'data': errormsg}) else: return JsonResponse({'status':False,'data':'用户被禁用'}) else: errormsg = '用户名或密码错误!' return JsonResponse({'status':False,'data':errormsg}) else: errormsg = '用户名或密码未输入!' return JsonResponse({'status':False,'data':errormsg}) else: return JsonResponse({'status':False,'data':'方法不允许'})
登录添加Mac地址参数
后端处理好之后,我们接着对桌面图形程序的代码进行调整。
首先引入 Mac 地址库:
from getmac import get_mac_address
然后,在登录槽函数 login() 里获取本机 Mac 地址并在登录请求时携带上这个参数:
# 登陆验证 def login(self): username = self.username_input.text() pwd = self.pwd_input.text() mac_address = get_mac_address() if username == '' or pwd == '': error_box = QtWidgets.QMessageBox() error_box.setWindowTitle("出错!") error_box.setIcon(QtWidgets.QMessageBox.Warning) error_box.setText("请输入用户名或密码") error_box.exec_() else: auth_url = 'http://127.0.0.1:8000/auth/' r = requests.post(auth_url, data={'username': username, 'password': pwd,'mac_address':mac_address}, timeout=10 ) if r.status_code == 200: resp_data = r.json() if resp_data['status']: self.main_window = MainWindow() self.main_window.show() self.close() else: error_box = QtWidgets.QMessageBox() error_box.setWindowTitle("出错!") error_box.setIcon(QtWidgets.QMessageBox.Warning) error_box.setText(resp_data['data']) error_box.exec_() else: error_box = QtWidgets.QMessageBox() error_box.setWindowTitle("出错!") error_box.setIcon(QtWidgets.QMessageBox.Warning) error_box.setText('登录出错') error_box.exec_()
下面,我们测试一下。
因为我们现在还没绑定 Mac 地址,所以登录验证 Mac 地址失败,用户就算密码正确也登录不了。
下面,我们为用户账号添加Mac地址:
如下图所示,现在已经可以登录了:
如果我们不需要对用户的Mac地址进行验证,可以通过 Mac状态进行设置:
这样,我们就完成了使用 Python 全栈实现桌面图形程序的用户 Mac 地址绑定。
有什么问题,欢迎留言讨论!