UserLogin 用户登录
账号授权模式的登录入口:用用户名 + 密码登录,可选同时传入卡密给账号续期,也支持 QQ 扫码登录。
| 项目 | 值 |
|---|---|
| action | UserLogin |
| 入口 | Handle POST https://www.a7p.cn/api/verify/{ApiPassword} |
| 是否计入验证统计 | 是 |
| 前置条件 | 账号已通过 UserRegin 注册 |
调用步骤
- 完成 Init 握手,拿到
ApiPassword。 - 采集机器码
Mac(用于换绑检测,强烈建议传)。 - 拼接明文:
action=UserLogin&UserName=账号&Password=密码;需要续期时追加&Card=卡密。 - RC4 加密 + MD5 签名,POST 到 Handle 接口。
code == 200→ 缓存data.token。- 若返回
1022,说明机器码变了,引导用户调用ChangeBind换绑。 - 启动定时器,每 5 分钟用
token调用UserHeartbeat(Type=user)。
请求参数
密码登录
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
action | string | 是 | 固定值 UserLogin |
UserName | string | 是 | 用户名。等价别名:username |
Password | string | 是 | 密码(明文,已由 RC4 整体加密传输)。等价别名:pwd、Pwd |
Card | string | 否 | 充值卡密。传入则登录成功后给该账号续期。等价别名:card |
Mac | string | 否 | 机器码,用于换绑检测。等价别名:mac、DeviceId |
明文示例:
text
# 仅登录
action=UserLogin&UserName=testuser01&Password=123456&Mac=MAC001
# 登录 + 卡密续期
action=UserLogin&UserName=testuser01&Password=123456&Card=6PCG-ZRSZ-EX83-YBEHQQ 扫码登录
QQ 登录是两步流程,需要传 LoginType=qq。
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
LoginType | string | 是 | 固定值 qq |
State | string | 第二步必填 | 第一步返回的 state 值 |
Mac | string | 否 | 机器码,登录成功后会更新到账号上 |
第一步 —— 获取扫码链接:
text
action=UserLogin&LoginType=qq返回:
json
{
"code": 200,
"message": "请扫码授权",
"data": {
"url": "https://graph.qq.com/oauth2.0/authorize?...",
"state": "8f3c21a5d7"
}
}第二步 —— 用 state 轮询确认(用户扫码后即可拿到登录结果):
text
action=UserLogin&LoginType=qq&State=8f3c21a5d7&Mac=MAC001轮询期间会返回 201,表示还没扫码,继续轮询即可,不是错误:
json
{ "code": 201, "message": "等待授权,请扫码后重试" }业务规则
- 必须先注册:账号不存在返回
1016,提示用户先调用UserRegin。 - 未激活拦截:账号没有任何激活记录,或激活已过期,返回
1005,提示用卡密激活/续期。 - 换绑检测:传入的
Mac与账号已绑定的机器码不同时,返回1022,data.remark里带着原绑定机器码;若换绑次数已达上限则先返回1021。 - 按次卡不能用于续期:
Card传了按次卡会返回1024。 - 续期算法:账号未过期则在原到期时间上叠加,已过期则从当前时间起算。
请求示例
python
# 复用 /api/handle 页面中的 handle() 与 rc4() 函数
API_PW = "A1B2C3D4E5F6G7H8I9J0K1L2M3N4O5P6"
plain = "action=UserLogin&UserName=testuser01&Password=123456&Mac=MAC001"
result = handle(API_PW, plain)
code = result["code"]
if code == 200:
token = result["data"]["token"]
print(f"登录成功,到期 {result['data']['expire_at']}")
elif code == 1022:
old_mac = (result.get("data") or {}).get("remark", "")
print(f"机器码已变更(原机器码 {old_mac}),请调用 ChangeBind 换绑")
elif code == 1016:
print("账号未注册,请先注册")
else:
print(f"登录失败 {code}: {result['message']}")csharp
// 复用 /api/handle 页面中的 A7Client
var client = new A7Client(apiPassword);
string plain = "action=UserLogin&UserName=testuser01&Password=123456&Mac=MAC001";
JsonElement result = await client.HandleAsync(plain);
int code = result.GetProperty("code").GetInt32();
switch (code)
{
case 200:
JsonElement data = result.GetProperty("data");
Console.WriteLine($"登录成功,到期 {data.GetProperty("expire_at").GetString()}");
break;
case 1022:
Console.WriteLine("机器码已变更,请调用 ChangeBind 换绑");
break;
case 1016:
Console.WriteLine("账号未注册,请先注册");
break;
default:
Console.WriteLine($"登录失败 {code}: {result.GetProperty("message").GetString()}");
break;
}javascript
// 复用 /sdk/nodejs 中的 A7Client
const client = new A7Client({ appId: '150018', appKey: 'YOUR_APP_KEY' })
await client.init()
const result = await client.call('UserLogin', {
UserName: 'testuser01',
Password: '123456',
Mac: 'MAC001',
})
if (result.code === 200) {
console.log('登录成功,到期', result.data.expire_at)
} else if (result.code === 1022) {
console.log('机器码已变更,请调用 ChangeBind 换绑')
} else {
console.error(`登录失败 ${result.code}: ${result.message}`)
}text
.版本 2
.子程序 A7_用户登录, 逻辑型
.参数 ApiPassword, 文本型
.参数 账号, 文本型
.参数 密码, 文本型
.局部变量 TimeStamp, 文本型
.局部变量 加密参数, 文本型
.局部变量 Sign, 文本型
.局部变量 返回文本, 文本型
.局部变量 状态码, 文本型
TimeStamp = 到文本 (时间_取现行时间戳 ())
加密参数 = RC4加密 (ApiPassword, "action=UserLogin&UserName=" + 账号 + "&Password=" + 密码 + "&Mac=" + 取机器码 ())
Sign = 取数据摘要 (到字节集 (ApiPassword + TimeStamp + 加密参数))
返回文本 = 到文本 (网页_访问 ("https://www.a7p.cn/api/verify/" + ApiPassword, 1, ;
"TimeStamp=" + TimeStamp + "&Sign=" + Sign + "&Data=" + 加密参数))
状态码 = JSON_解析 (返回文本, "code")
.判断开始 (状态码 = "200")
全局_Token = JSON_解析 (返回文本, "data.token")
返回 (真)
.判断 (状态码 = "1022")
信息框 ("检测到更换设备,请先换绑机器码", 0, )
.默认
信息框 ("登录失败:" + JSON_解析 (返回文本, "message"), 0, )
.判断结束
返回 (假)成功响应
仅登录(不传 Card)
json
{
"code": 200,
"message": "success",
"data": {
"username": "testuser01",
"device_id": "MAC001",
"expire_at": "2026-06-03 12:00:00",
"status": "active",
"token": "9c4d2e01f7b8443a...",
"remark": ""
}
}| 字段 | 类型 | 说明 |
|---|---|---|
username | string | 当前登录的用户名 |
device_id | string | 账号绑定的机器码,未绑定时为空字符串 |
expire_at | string | 到期时间 YYYY-MM-DD HH:mm:ss |
status | string | active = 正常 |
token | string | 登录凭证,40 位随机串。心跳时用 Type=user 携带 |
remark | string | 后台备注/消息,无消息时为空字符串 |
登录 + 卡密续期(传 Card)
json
{
"code": 200,
"message": "success",
"data": {
"username": "testuser01",
"expire_at": "2026-07-02 12:00:00",
"added_days": 30,
"status": "active"
}
}| 字段 | 类型 | 说明 |
|---|---|---|
username | string | 用户名 |
expire_at | string | 续期后的新到期时间 |
added_days | int | 本次增加的天数 |
status | string | active |
注意
传入 Card 的续期分支不返回 token。 客户端若需要 token,请先不带 Card 登录一次拿 token,再单独调用 UserRecharge 续期;或续期成功后再登录一次。
QQ 扫码登录成功
json
{
"code": 200,
"message": "success",
"data": {
"username": "testuser01",
"device_id": "MAC001",
"expire_at": "2026-06-03 12:00:00",
"status": "active",
"token": "0f2b9c...",
"remark": "QQ昵称"
}
}失败响应
json
{ "code": 1003, "message": "密码错误", "data": null }json
{ "code": 1005, "message": "未激活,请使用卡密激活后登录", "data": null }json
{ "code": 1006, "message": "账户已被停封", "data": { "remark": "违规" } }json
{ "code": 1016, "message": "用户未注册,请先调用 UserRegin 注册", "data": null }json
{ "code": 1021, "message": "换绑次数已达上限,最多允许3次", "data": null }json
{ "code": 1022, "message": "机器码已变更,请调用 ChangeBind 换绑", "data": { "remark": "OLD-MAC-001" } }json
{ "code": 1024, "message": "按次卡密不能用于用户账户充值,请使用卡密登录方式", "data": null }错误码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
201 | 等待 QQ 授权 | 非错误,继续轮询 |
1003 | 密码错误 | 提示用户重输密码 |
1004 | 充值卡密无效 | Card 不存在或不属于当前产品 |
1005 | 未激活 / 已过期 | 引导用户用卡密激活或续期 |
1006 | 账户已被停封 / 禁用 | 读取 data.remark 展示原因 |
1013 | 参数不完整 | UserName 与 Password 必填 |
1016 | 用户未注册 / QQ 未绑定账号 | 引导先注册 |
1021 | 换绑次数已达上限 | 联系软件作者在后台重置 |
1022 | 机器码已变更 | 调用 ChangeBind 换绑,data.remark 是原机器码 |
1023 | 已被列入黑名单 | IP 或机器码命中黑名单 |
1024 | 按次卡密不能充值 | 按次卡请走 SingleLogin |
完整列表见错误码对照表。
相关文档
- UserRegin 用户注册 —— 登录前先注册
- ChangeBind 换绑设备 —— 处理
1022 - UserRecharge 用户续期 —— 独立的续期入口
- UserHeartbeat 心跳检测 —— 登录后保持在线
- SDK 实现:易语言 · C# · Python · Node.js