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

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

猜你也喜欢

发表评论

邮箱地址不会被公开。