登录流程
密码式
密码式为纯API流程,下面是登录API:
终结点
https://ydzx.panretro.com/external/api/v1/oauth2/token
参数
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
grant_type | 是 | 字符串 | 授权类型,这里固定为 password(密码模式) |
client_id | 是 | 字符串 | 客户端 ID,用于标识应用 |
client_secret | 是 | 字符串 | 客户端密钥,用于验证客户端身份 |
username | 是 | 字符串 | 用户名,用于密码模式下的用户认证 |
password | 是 | 字符串 | 用户密码,用于密码模式下的用户认证 |
scope | 否 | 字符串 | 访问范围,用空格分隔的字符串,默认服务端可访问全部 |
响应:
{
"code": 200,
"msg": "ok",
"data": null,
"token_type": "bearer",
"access_token": "UnGOte...",
"refresh_token": "nfnhqx...",
"expires_in": 7200,
"refresh_expires_in": 2592000,
"client_id": "1001",
"scope": ""
}
| 参数名 | 类型 | 说明 |
|---|---|---|
code | 整数 | 状态码,200 表示请求成功 |
msg | 字符串 | 请求返回的信息,一般为 "ok" 或错误描述 |
data | 任意 | 返回的数据内容,这里为 null |
token_type | 字符串 | Token 类型,一般为 "bearer",表示 Bearer Token |
access_token | 字符串 | 用于访问受保护资源的访问令牌 |
refresh_token | 字符串 | 刷新令牌,用于在 access_token 过期后获取新的 access_token |
expires_in | 整数 | access_token 的有效期,单位为秒 |
refresh_expires_in | 整数 | refresh_token 的有效期,单位为秒 |
client_id | 字符串 | 客户端 ID,用于标识应用 |
scope | 字符串 | 授权范围 |
Python代码示例:
import requests
url = "https://ydzx.panretro.com/external/api/v1/oauth2/token"
payload = {
"grant_type": "password",
"client_id": "f81ddf2e519aab618c0bd8fef80ead2d",
"client_secret": "123456789",
"username": "1",
"password": "1"
}
# 发起 POST 请求获取 token
response = requests.post(url, data=payload)
# 检查请求是否成功
if response.status_code == 200:
token_data = response.json()
access_token = token_data.get("access_token")
refresh_token = token_data.get("refresh_token")
expires_in = token_data.get("expires_in")
print("Access Token:", access_token)
print("Refresh Token:", refresh_token)
print("Expires In:", expires_in)
else:
print("请求失败,状态码:", response.status_code)
print("响应内容:", response.text)
MD5 安全登录
前提:用户必须先用明文密码登录过一次网页(
/user/login),服务端自动存储md5PasswordHash。
标准 /token 端点(密码模式)已内置 MD5 支持:服务端先尝试明文密码,失败后自动尝试 MD5 校验。客户端只需将 password 传为明文密码的 MD5(32 位小写)即可,无需额外端点。
Python 示例:
import hashlib
import requests
password = "mypassword"
md5 = hashlib.md5(password.encode()).hexdigest()
resp = requests.post(
"https://ydzx.panretro.com/external/api/v1/oauth2/token",
data={
"grant_type": "password",
"client_id": "f81ddf2e519aab618c0bd8fef80ead2d",
"client_secret": "123456789",
"username": "1",
"password": md5, # 传 MD5 即可
}
)
print(resp.json()["access_token"])
授权码
模式概述
授权码模式(Authorization Code Grant)主要用于 服务器端应用(例如 Web 应用)获取访问令牌,安全性较高。流程如下:
- 用户访问客户端应用,客户端引导用户到授权服务器登录。
- 用户授权后,授权服务器将 授权码(authorization code) 回传给客户端。
- 客户端使用授权码向授权服务器请求 access_token。
- 授权服务器返回 access_token(可选返回 refresh_token)。
- 客户端使用 access_token 访问受保护的资源。
请求流程
1. 用户授权请求(获取授权码)
首先,跳转到以下链接
https://ydzx.panretro.com/external/api/v1/oauth2/authorize?
response_type=code&
client_id=f81ddf2e519aab618c0bd8fef80ead2d&
client_secret=123456789&
redirect_uri=http://example.com/login&
scope=userinfo chat
参数说明:
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
response_type | 是 | 字符串 | 固定为 code,表示请求授权码 |
client_id | 是 | 字符串 | 客户端 ID |
redirect_uri | 是 | 字符串 | 授权成功后回调地址 |
scope | 否 | 字符串 | 请求的权限范围,用空格分隔 |
state | 否 | 字符串 | 防止 CSRF 攻击,客户端自定义 |
Scope范围
Scope用于定义令牌的权限范围,权限码如下,多个权限码使用空格分割
| 权限 | 说明 |
|---|---|
userinfo | 用于获取用户信息、ID |
chat | 用于获取用户群聊信息、发送信息 |
此时应有登录框出现

用户输入账户密码后,点击登录,会进行二次询问

点击同意后,完成授权过程
成功授权后,浏览器会跳转到:
http://example.com/login?code=AUTH_CODE&state=xyz123
此时你的服务器后端收到的AUTH_CODE为我们获取的授权码
2. 使用授权码换取 access_token
请求示例:
https://ydzx.panretro.com/external/api/v1/oauth2/token
grant_type=authorization_code&
code={AUTH_CODE}&
client_id=f81ddf2e519aab618c0bd8fef80ead2d&
client_secret=123456789
scope=userinfo chat
参数说明:
| 参数名 | 必填 | 类型 | 说明 |
|---|---|---|---|
grant_type | 是 | 字符串 | 固定为 authorization_code |
code | 是 | 字符串 | 授权码 |
client_id | 是 | 字符串 | 客户端 ID |
client_secret | 是 | 字符串 | 客户端密钥 |
scope | 否 | 字符串 | 请求的权限范围,用空格分隔 |
响应:
{
"code": 200,
"msg": "ok",
"data": null,
"token_type": "bearer",
"access_token": "UnGOte...",
"refresh_token": "nfnhqx...",
"expires_in": 7200,
"refresh_expires_in": 2592000,
"client_id": "1001",
"scope": ""
}
| 参数名 | 类型 | 说明 |
|---|---|---|
code | 整数 | 状态码,200 表示请求成功 |
msg | 字符串 | 请求返回的信息,一般为 "ok" 或错误描述 |
data | 任意 | 返回的数据内容,这里为 null |
token_type | 字符串 | Token 类型,一般为 "bearer",表示 Bearer Token |
access_token | 字符串 | 用于访问受保护资源的访问令牌 |
refresh_token | 字符串 | 刷新令牌,用于在 access_token 过期后获取新的 access_token |
expires_in | 整数 | access_token 的有效期,单位为秒 |
refresh_expires_in | 整数 | refresh_token 的有效期,单位为秒 |
client_id | 字符串 | 客户端 ID,用于标识应用 |
scope | 字符串 | 授权范围 |
完成
至此,登录流程全部结束,access_token即为我们需要的令牌
但令牌并不是长期有效的,他受expires_in的限制,有时效性
下一步,我们需要使用refresh_token续期