使用 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 地址绑定。

有什么问题,欢迎留言讨论!

分类目录: Web开发

标签: django