吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1258|回复: 0
收起左侧

[Python 转载] 【Python】基于基于Pyqt和Bmob数据库的在线登录模块

[复制链接]
TheLord 发表于 2021-8-26 20:02

0x0 起因

因为不会给动图打码,就只用静态截图了。

hu1HMQ.png

这个想法其实是因为之后要把之前写的易班工具拿给新来的干事用,考虑到部分人没有基础,让他们在源码里面改参数不太现实(可能教他们配置环境都会很头疼)。于是就产生了给工具写一个GUI的想法,在看了Tkinter和PyQt之后感觉似乎Qt的资料要多一点点,于是选择了Qt。

稍微扯远了点,这个小模块就是一个小练手,本质上这个小模块的登录等一系列的验证都是通过requests库Bmob官方库实现的;我想的是,先至少摸到Qt门槛,再去把工具接进去,不然不知道要遇到多少奇奇怪怪的bug。

接着就开始着手去做这个小程序了

目前已实现功能:

  1. 通过Bmob验证用户身份
  2. 单用户登录校验码,一次性校验码
  3. 登录记录
  4. 通过Server酱推送登录通知

计划功能:

  1. 添加校验码
  2. 本地记住BmobKey

0x1 UI部分

昨天(8/25)下午开始画UI,有一说一,QtDesigner是个好东西,拖几下基本框架就有了。然后稍微改一下细节,就差不多了。左边这个是QtDesigner直出的UI,稍微缺点内味。利用万能的互联网发现Qt可以支持类似CSS的样式文件——QSS,二者语法是完全一样的。然后在GayHub上头找到了一个现成的Qss模板,稍微修改了一下,就有了右侧的这样。圆角yyds!!!

PS:本来还想把整个窗体都做成圆角的,但是好像挺复杂的样子,就放弃了。

heGEFK.png

我觉得我审美应该是挺在线的,我把截图拿给女朋友和好兄弟们看,评价都是

有点丑,但是又不知道哪丑,像是世纪初的软件

多少想哭。


撇开美观与否,简单聊一聊我的思路。

通过小学数学学到的数数方法,可以知道整个窗口上有六个输入栏,三个按钮和一个CheckBox(暂时加码记住Key暂时是没用的,还没写功能)。

整个小程序的逻辑是,先输入Bmob的Key,选择性输入Server酱的SendKey;先简单判断Bmob的那两个输入栏是否为空,为空则显示提示文字,如果有输入则尝试连接Bmob(暂时没做更详细的验证),并且激活下面的登录按钮,因为按照当时写的登录函数的逻辑,如果都输入为空的话,似乎会出现奇怪的Bug直接卡死,大概就是下面这个样子。主要是懒得改

hn48l8.gif

接着再输入账号、密码和校验码(选填),再连接Bmob验证,并根据返回的结果显示对应的文字提示。其中是否需要校验码可以在Bomb后台对表单进行修改来实现控制。

以上是已实现的功能,下面是计划中的功能。

第一个就是记住Key的功能

每一次打开都要输入显得挺麻烦的,可以考虑在根目录生成cfg文件,记录Key,在程序加载时先判断根目录是否有cfg文件,如果有就看看是否保存有key并且修改CheckBox状态,如果没有就新生成一个。

heab1f.png

第二个就是向后台增加校验码

函数其实已经写好了,但是还没写到主程序里。这个各位就自己看看ActCode.py就可以了,很简单的一个功能。

其他就没啥好说的了吧,QtDesigner那个东西没啥好说的,半小时应该就能掌握基本操作了。


0x2 登录函数实现

这个函数其实挺早就写好了,但是当时是控制台脚本,就花了点时间去把他给按照我对Qt粗浅的理解修改了一下。下面简单的说一下思路吧。

首先要说明的是,整个业务逻辑都是依赖于Bmob的官方库实现的,Bmob官方也给了一些简单的例子(虽然都是18年的了),先行阅读Bmob的官方文档有利于理解后面的内容。因为没有写创建用户的脚本,所以创建用户等操作都需要自己先行手动创建,具体可以参考下方截图抄作业。

(放图)

链接:Bmob文档

有的老哥会问,为什么不用MySQL或者MongoDB这些数据库呢?

我学的不是计算机专业,纯属自己瞎鼓捣着玩,也就脚本小子的程度,我对数据库的认识就只有rm -rf /*这样,虽然有自己的服务器,但是平时玩WordPress这些基本上都是能不动就不会去动数据库。所以就没有去系统学习过数据库相关的内容。Bmob这个网站我高三就用过了,感觉也海星,挂一点小玩具的数据在上头跑路了也不影响。

最重要的就是他挺简单的,好上手,基本上当时从看他的Demo到自己写出来这个登录程序也就花了小半天,可以说是有Python基础基本就能懂,也不需要额外配置什么,直接注册个账号创建应用有Key就可以开搞了;而且,他免费(这才是重中之重,盒盒盒)。

Bmob快给我打钱!!!

1. 登录&验证

首先,Bmob官方给了一个登录函数

userLogin(username, password) HttpResponse 用户通过账号、密码登陆
def Login(user, passwd, APP_id, API_key):
    b = Bmob(APP_id, API_key) #实例化
    account = b.userLogin(user, passwd)
    return account.status #返回登录结果

其中status为Bmob模块内置的响应类型

status str 状态信息

这里如果密码账号正确就会返回字符串“OK”,那么很简单的一个if判断就可以判断登录结果了。

if Login(user, passwd, APP_id, API_key) == "OK":
    print("登录成功!")
else:
    print("用户名或密码错误!")

实现登录功能后,我们来解决校验码的问题。首先肯定是检查当前用户是否需要校验码,然后再检查用户提供的校验码是否存在。这个就没有现成的方法来调用了,得自己写,但是也不难。

通过官方文档我们可以找到find函数,似乎符合我们的要求,并且官方也给了具体的例子

b = Bmob("appid", "restkey")
b.find(
    table, # 设置查询表单
    where = None, # 设置查询条件, dict或BmobQuerier
    limit = None, # 设置最大返回行数,int
    skip = None, # 设置跳过的个数,int
    order = None, # 排序规则,str
    include = None, # 需要返回详细信息的Pointer属性,str
    keys = None, # 需要返回的属性,str
    count = None, # 统计接口: 返回数量,int
    groupby = None, # 统计接口: 根据某列分组,str
    groupcount = None, # 统计接口: 分组后组内统计数量,bool
    min = None, # 统计接口: 获取最小值,str
    max = None, # 统计接口: 获取最大值,str
    sum = None, # 统计接口: 计算总数,str
    average = None, # 统计接口: 计算平均数,str
    having = None, # 统计接口: 分组中的过滤条件,str
    objectId = None # 查询单条数据,str
)

可以说是就差把程序写好丢你脸上了。table是要查询的表单,待会儿我们去建一个存放校验码的表。然后就是where,可以看到他有两种方法,一个是dict、一个是BmobQuerier。先不考虑dict,看看Bmob自己给的这个方法,通过阅读文档可以找到这么一段说明

BmobQuerier

类方法: 返回类型均为 BmobQuerier (以链式调用)

方法体 描述
addWhereExists(key) 某字段有值
addWhereNotExists(key) 某字段无值
addWhereEqualTo(key, value) 某字段等于
addWhereNotEqualTo(key, value) 某字段不等于
addWhereGreaterThan(key, value) 某字段大于
addWhereGreaterThanOrEqualTo(key, value) 某字段大于等于
addWhereLessThan(key, value) 某字段小于
addWhereLessThanOrEqualTo(key, value) 某字段小于等于
addWhereRelatedTo(table,toObjId,toKey) 在某表作为Relation关联起来的数据
addWhereNear(key,bmobGeoPoint,maxMiles,maxKM,maxRadians) 地理位置在一定范围内
addWhereWithinGeoBox(key,southwest,northeast) 地理位置在矩形范围内
addWhereContainedIn(key,objs) 值在列表内
addWhereNotContainedIn(key,objs) 值不在列表内
addWhereContainsAll(key,objs) 列表包含全部项
addWhereStrContains(key,regex) String类型模糊查询
addWhereMatchesSelect(key,innerQuery,innerKey,innerTable,isMatch) 某项符合子查询
addWhereInQuery(key,value,className,isIn) 某项包含在子查询

那么,我们如果要检查一个校验码是否存在,那么就是去遍历表,挨个比对是否有这么一个校验码;不难发现上面有一个方法可以实现这个功能——addWhereEqualTo(key, value),需要注意的是这里是用value的值去和key这个字段里的所有值进行比较,所有就不用再去写循环了,很棒

b = Bmob(APP_id, API_key)
b.find('ActCode', where=BmobQuerier().addWhereEqualTo("actcode", jycode)).queryResults[0]['objectId']

其中queryResults为Bmob模块的内置响应类型

queryResults dict 返回的bmob查询数据

这里我们用jycode在表ActCode中的actcode字段中进行对比,如果jycodeactcode字段中存在,那么将会返回该校验码对应的objectid;如果不存在,则b.find(...)将不会存在queryResults,发生IndexError错误,那么可以使用try...except...的方法来写这个验证,即

def actcode(code, APP_id, API_key):
    b = Bmob(APP_id, API_key)
    try:
        object_id = b.find('ActCode', where=BmobQuerier().addWhereEqualTo("actcode", code)).queryResults[0]['objectId']
        b.remove('ActCode', object_id)
        return code
    except IndexError:
        return 0

这里的remove函数用来删除上面使用的这个校验码,通过返回的objectid,在ActCode表中删除对应行

remove(className, objectId) 删除数据表中的一行

以上,我们实现了登录和验证校验码的功能

2. 校验码控制

这里,我们将实现单用户校验码控制,即可设置哪些用户需要校验码登录,哪些用户不需要。

主要的思路和上面的验证码校验差不多,我们通过在_User表中,新建一个校验码控制字段ctrlcode,通过对ctrlcode字段的修改实现单个用户的校验码设置。直接上代码

def Ctrl(User, APP_id, API_key):
    b = Bmob(APP_id, API_key)
    flag = b.find('_User', where=BmobQuerier().addWhereEqualTo("username", User)).queryResults[0]['ctrlcode']
    return flag

这里返回的是查询的结果,我们将ctrlcode字段设为Number或者Bool型都是可以的,将函数返回的结果代入到大的登录函数中,就可以在登录时决定是否调用校验码验证函数。

3. 登录记录

这里需要将登录用户和使用的校验码记录下来,因为Bmob自带时间记录,所以不再单独写函数上传时间。需要用到insert函数:

insert(className, data) 往数据表中添加一行

传入用户名和使用的校验码即可,如果不使用校验码则将校验码设为用户名:

def up_log(User, code, APP_id, API_key):
    b = Bmob(APP_id, API_key)
    b.insert('log', {
            'username': user,
            'usecode': code
    })
objectId usecode username createdAt updateAt
82faea999d tool-6t&ZFaq<Zz toolman 2021-08-25 22:23:04 2021-08-25 22:23:04

这样就向log表中上传了登录信息,并且如果用户使用过校验码也能记录校验码。

4. Server酱推送

通过server酱的官方文档,我们直接使用requests库来实现,这里不多赘述,直接看代码

def wxpush(user, code, send_key):
   sApi = 'https://sctapi.ftqq.com/' + send_key + '.send'
   requests.post(sApi, {
      'title': '登录提示',
      'desp': '用户 ' + user + ' 登录成功!\n使用了激活码:' + code
   })

最后将这些模块组装起来就可以了。


0x3 Qt踩坑部分

这一小节我认为是我整篇帖子里最有用的部分。我希望把我在写这个小程序时遇到的问题分享出来,大家自己上手的时候就可以避免这些情况。

这点明天再更新,今晚收拾东西,明儿回学校,四月份受伤韧带断了就一直休学在家里,太难受了。

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 14:41

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表