Skip to main content

登录流程

密码式

密码式为纯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 应用)获取访问令牌,安全性较高。流程如下:

  1. 用户访问客户端应用,客户端引导用户到授权服务器登录。
  2. 用户授权后,授权服务器将 授权码(authorization code) 回传给客户端。
  3. 客户端使用授权码向授权服务器请求 access_token
  4. 授权服务器返回 access_token(可选返回 refresh_token)。
  5. 客户端使用 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用于获取用户群聊信息、发送信息

此时应有登录框出现

img_6.png

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

img_7.png

点击同意后,完成授权过程

成功授权后,浏览器会跳转到:

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续期