5

使用 Python 全栈实现桌面图形程序的用户 Mac 地址绑定

 2 years ago
source link: https://zmister.com/archives/1616.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

在上一篇文档,我们介绍了使用 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

2021-06-19_094819.png

在 /qt_login_backend/qt_login_backend/settings.py 文件中,添加如下代码以指定用户认证的模型:

AUTH_USER_MODEL = 'app_admin.User'

创建超级用户:

2021-06-17_110516.png

接着,在 /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 模型已经添加到了管理页面中:

2021-06-19_095348.png

用户列表中显示了我们自定义的 Mac启用状态字段和 Mac地址字段:

2021-06-19_095541.png

编写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_()

下面,我们测试一下。

qt-login-auth-mac_1624068831.gif

因为我们现在还没绑定 Mac 地址,所以登录验证 Mac 地址失败,用户就算密码正确也登录不了。

下面,我们为用户账号添加Mac地址:

2021-06-19_101540.png

如下图所示,现在已经可以登录了:

qt-login-auth-mac-yes_1624069063.gif

如果我们不需要对用户的Mac地址进行验证,可以通过 Mac状态进行设置:

2021-06-19_101958.png

这样,我们就完成了使用 Python 全栈实现桌面图形程序的用户 Mac 地址绑定。

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK