锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 默认分类
  3. 授权码机制 V2.1

授权码机制 V2.1

0
  • 默认分类
  • 发布于 2024-10-07
  • 13 次阅读
黄健
黄健

大家好,我是机灵鹤。

根据读者朋友们反馈的问题和建议,对 授权码 V2.0 版本做了一些优化。

优化内容主要解决了以下几个问题:

  1. 优化了授权机制中的时间校验逻辑,避免用户通过回调本地时间来绕过授权机制的问题。

  2. 封装和简化了授权接口,开发者可以更方便地接入到自己的程序中。

1. 授权时间校验逻辑优化

授权码机制 V2.0 是属于 离线校验 的授权机制。

由于程序校验时,获取的是机器的 本地时间,所以用户在授权到期以后,可以通过回调本地时间,轻松绕过授权机制,继续使用软件。

为此,我通过网上查阅资料,跟一些读者朋友交流讨论,找到了一个相对可行的解决方案。

下面跟大家分享一下。

1.1 有网络时优先获取在线时间

虽然授权码机制 V2.0 是离线校验,但是运行程序的电脑并不一定是断网的。

所以,我们可以在有网络的情况下,优先使用在线时间,断网情况下,再使用本地时间。

示例代码如下:

import http.client
import time

def getTime():
    try:
        # 使用网络时间
        conn = http.client.HTTPConnection('www.baidu.com')
        conn.request("GET", "/")
        r = conn.getresponse()
        ts =  r.getheader('date')
        ltime= time.strptime(ts[5:25], "%d %b %Y %H:%M:%S")
        return int(time.mktime(ltime)+8*60*60)
    except:
        # 使用本地时间
        return int(time.time())

网络时间从 百度 官方网站的响应头中获取。

一来不用担心网站关停导致时间获取失败;二来也不用担心网站提供错误的时间数据。

1.2 授权文件记录上次使用时间

通过 1.1 的方法,我们可以在用户机器有网络的情况下,获取到准确的时间。

但是如果用户运行程序前手动断网,或者电脑本身就不联网,该怎么办?

为此,我们想到了,在授权文件中记录程序 上次使用时间,如果发现 当前时间 早于上次使用时间,则说明用户调整过本地时间。

校验逻辑示意图如下:

在每次启动程序时,读取上次使用时间 lastUseTime,与当前时间 curTime 比较,

  • 若 curTime 早于 lastUseTime,说明时间异常,用户有可能回调系统时间了。

  • 若 curTime 晚于授权到期时间 endTime,说明授权到期了。

  • 若 curTime 在 lastUseTime ~ endTime 之间,可以正常使用。此时将 curTime 写入配置,替换 laseUseTime。

这样 lastUseTime 会不断逼近 endTime ,直到超过使用期限。

虽然用户可以微调系统时间(每次调到不早于上次使用时间)延长使用时间,但总体来说,授权使用时间还是被限定在一个可控的范围内。

1.3 授权码本身添加时效

聪明的你可能想到了。

既然 上次使用时间 是记录在本地配置中的,那如果用户在授权到期以后,先删掉授权文件,再回调时间,然后用原先的授权码进行授权,岂不是又可以无限重复使用了?

为了解决这个问题,我想到了 给授权码本身添加时效。

简单来说,授权码中会额外携带一条时间信息:授权码到期时间。

授权码到期时间控制的是授权码的有效时间,授权码需要在此之前使用,逾期失效,需要重新申请。

举个例子:

假设当前时间是 2024-10-1 00:00:00。

现在生成了一个授权码,这个授权码携带的时间信息为:

  • 授权到期时间:2024-11-1 00:00:00

  • 授权码到期时间:2024-10-1 00:10:00

也就是说,用户需要在 10 分钟 之内使用授权码激活程序,逾期授权码就会失效,需要重新申请。

而在成功授权激活后,用户可以在 1 个月 内正常使用程序。

这样,授权码添加有效期之后,用户也就无法在授权到期以后,使用原来的授权码重新激活使用了。

以上方案虽然并不能保证可以彻底解决问题,但是也可以在一定程度上提高用户作弊的门槛了。

2. 开发者接口封装

不少读者跟我沟通和反馈过,就是授权码机制 V2.0 是挺好的,但是他们的程序各式各样,如何在他们的程序里无缝接入授权机制,却也难住了不少人。

于是,我将之前的代码部分重构,封装好接口,提供给开发者调用。

2.1 机器码生成接口

机器码是通过 主板序列号,Mac 地址,硬盘序列号,CPU序列号 通过一定算法计算得到的。

在跟读者的沟通中得知,他们的用户由于使用虚拟机/需要重装系统/更换硬盘等等情况,部分硬件参数会经常变动,导致机器码经常变化。

所以在机器码生成接口中,我将四个参数设置成可选项,开发者可根据实际情况,选择合适的硬件参数来生成机器码。

函数原型:

def getMachineCode(useMac = True, useCpu = True, useDisk = True, useBoard = True)

参数说明:

参数

说明

useMac

生成机器码时,是否使用 Mac 地址,默认为 True

useCpu

生成机器码时,是否使用 CPU 序列号,默认为 True

useDisk

生成机器码时,是否使用硬盘序列号,默认为 True

useBoard

生成机器码时,是否使用主板序列号,默认为 True

注:四个参数须至少有一个为 True,否则生成的机器码为固定值,无法与机器一一对应。

返回说明:

正常情况下,会返回一段 32 位长度的字符串,形如:EE51BF4CADD3899E037C24F218CCFD8F 。

2.2 授权校验接口

开发者可以调用此接口来进行授权校验。

在校验成功的同时,会自动更新本地配置文件中的上次使用时间信息。

函数原型:

def CheckAuth()

返回说明:

校验通过时,函数会返回下述 Json 数据:

{
     "errCode": 10000,
     "errInfo": "授权验证通过,欢迎使用。授权有效期截至:2024-10-03 14:30:41"
}

校验失败时,会返回如下的 Json 数据。

{
     "errCode": 10001,
     "errInfo": "[错误码 10001] 软件未授权,请使用授权码激活后使用。"
}

参数说明:

参数

说明

10000

成功

10001

软件未授权

10002

授权文件损坏

10003

授权码与本机的机器码不匹配

10004

授权码已过期

10005

本地时间异常

10006

网络请求超时

10007

授权码解析失败

10008

此授权码已失效

2.3 授权激活接口

开发者可以调用此接口来进行授权激活。

在激活成功的同时,会在本地创建授权配置文件。

函数原型:

def Activate(activeCode)

参数说明:

参数

说明

activeCode

授权码

返回说明:

校验通过时,函数会返回下述 Json 数据:

{
     "errCode": 10000,
     "errInfo": "授权验证通过,欢迎使用。授权有效期截至:2024-10-03 14:30:41"
}

校验失败时,会返回如下的 Json 数据。

{
     "errCode": 10001,
     "errInfo": "[错误码 10001] 软件未授权,请使用授权码激活后使用。"
}

参数说明:

参数

说明

10000

成功

10001

软件未授权

10002

授权文件损坏

10003

授权码与本机的机器码不匹配

10004

授权码已过期

10005

本地时间异常

10006

网络请求超时

10007

授权码解析失败

10008

此授权码已失效

3. 在程序中接入授权机制示例

3.1 示例代码

# 导入授权模块
from myAuthMgr import myAuthMgr, ErrorCode

def main():
    # 授权校验的逻辑写在最开始,校验通过了再执行你自己的代码
    checkInfo = myAuthMgr.CheckAuth()       # 调用校验接口,授权校验
    print(checkInfo["errInfo"])
    if checkInfo["errCode"] != ErrorCode.SUCCESS:       # 返回码不是 SUCCESS(10000),说明校验失败
        print("请联系管理员获得授权码,机器码:", myAuthMgr.machine_code)           # 机器码
        keyCode = input("请输入激活码:")
        activeInfo = myAuthMgr.Activate(keyCode)        # 调用激活接口,进行授权激活
        print(activeInfo["errInfo"])
        
        if activeInfo["errCode"] != ErrorCode.SUCCESS:  # 返回码不是 SUCCESS(10000),说明激活失败
            return

    # 以下是你自己的程序代码
    print("Hello World")


if __name__ == "__main__":
    main()

3.2 运行效果

首次运行程序(未授权)。

输入授权码,激活成功。

再次启动程序,通过读取本地授权文件,校验通过。

回调本地时间后,识别到本地时间异常,校验失败。

超过授权码的有效期,授权码失效,需要重新生成。

标签: #知识库 257
相关文章
最全的办公楼智能化解决方案

最全的办公楼智能化解决方案 2024-10-16 08:40

办公楼综合体智能化如何建设?有哪些系统?近几年,办公楼智能化的项目越来越多,不少项目经理都参与其它,同事办公楼综合体也是弱电系统涉及的最多的项目之一,本期我们一起来看下,最全的办公楼项目智能化设计方案。

规范标准查询、下载网站 2024-10-12 16:41

我们在工作中经常需要用到各种各样的规范标准,这里给大家介绍一些免费查询和下载规范的网站,个人亲测可用。 标准查找查新网站 工标网: http://www.csres.com/ 中国国家标准化管理委员会:http://openstd.samr.gov.cn/bzgk/gb/index 全国标准信息公共

【计算机网络】网络层协议解析 2024-10-08 11:24

网络层的两种服务 IPv4 * 分类编址 划分子网 无分类地址 IPv4地址应用 IP数据报的发送和转发过程 * 主机发送IP数据报 路由器转发IP数据报 IPv4数据报首部格式 ICMP网际控制报文协议 虚拟专用网VPN与

FFmpeg教程(超级详细版) 2024-10-08 11:24

一、参考资料 通过ffmpeg把图片转换成视频 FFmpeg命令(一)、使用filter_complex命令拼接视频 FFmpeg 视频处理入门教程给新手的 20 多个 FFmpeg 命令示例 FFmpeg命令行转码

计算机网络:物理层 —— 数据的传输方式 2024-10-08 11:24

文章目录 * 传输方式 * 串行传输 * 串行传输方式 特点 应用 并行传输 * 特点 应用 网卡的串/并转换 同步传输 * 同步时钟频率的误差问题 特点 应用<

授权码机制 V2.1 2024-10-07 10:26

大家好,我是机灵鹤。 根据读者朋友们反馈的问题和建议,对 授权码 V2.0 版本做了一些优化。 优化内容主要解决了以下几个问题: 优化了授权机制中的时间校验逻辑,避免用户通过回调本地时间来绕过授权机制的问题。 封装和简化了授权接口,开发者可以更方便地接入到自己的程序中。

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.