一、接口概述
本 SSO(单点登录)鉴权 API 提供统一的用户认证服务,允许外部系统接入并使用当前系统的用户体系进行身份验证。
1.1 服务地址
| 环境 | 基础URL |
|---|---|
| 生产环境 | https://yzztcl.cn/api/sso |
1.2 认证方式
所有请求必须在请求头中携带以下客户端凭证:
| 请求头 | 必填 | 说明 |
|---|---|---|
X-Client-Id |
✅ | 客户端ID,由管理员在后台配置 |
X-Client-Secret |
✅ | 客户端密钥,由管理员在后台配置 |
1.3 请求格式
- Content-Type:
application/x-www-form-urlencoded或application/json - 字符编码: UTF-8
1.4 响应格式
所有接口返回 JSON 格式数据:
{
"success": true,
"message": "操作成功",
"data": {}
}
| 字段 | 类型 | 说明 |
|---|---|---|
success |
boolean | 操作是否成功 |
message |
string | 提示信息 |
data |
object | 返回数据 |
二、接口列表
2.1 检查登录状态
接口地址: GET /api/sso/check-login
功能描述: 检查当前会话用户是否已登录
请求示例
curl -X GET "https://yzztcl.cn/api/sso/check-login" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "Cookie: nova_session=your-session-cookie"
成功响应
{
"success": true,
"data": {
"logged_in": true,
"user_id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"status": 1
}
}
失败响应
{
"success": false,
"message": "用户未登录",
"data": {
"logged_in": false
}
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
logged_in |
boolean | 是否已登录 |
user_id |
int | 用户ID |
username |
string | 用户名 |
email |
string | 邮箱 |
role |
string | 角色(admin/user) |
status |
int | 状态(1=正常,0=禁用) |
2.2 获取用户详细信息
接口地址: GET /api/sso/user-info
功能描述: 获取当前登录用户的完整信息
请求示例
curl -X GET "https://yzztcl.cn/api/sso/user-info" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "Cookie: nova_session=your-session-cookie"
成功响应
{
"success": true,
"data": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"role_name": "管理员",
"status": 1,
"avatar": null,
"created_at": "2024-01-01 10:00:00",
"updated_at": "2024-01-15 14:30:00"
}
}
2.3 用户登录
接口地址: POST /api/sso/login
功能描述: 通过用户名和密码登录系统
请求参数
| 参数 | 必填 | 类型 | 说明 |
|---|---|---|---|
username |
✅ | string | 用户名或邮箱 |
password |
✅ | string | 用户密码 |
请求示例
curl -X POST "https://yzztcl.cn/api/sso/login" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "username=admin&password=your-password"
成功响应
{
"success": true,
"message": "登录成功",
"data": {
"id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"role_name": "管理员"
}
}
失败响应
{
"success": false,
"message": "用户名或密码错误"
}
2.4 用户退出登录
接口地址: POST /api/sso/logout
功能描述: 清除当前会话登录状态
请求示例
curl -X POST "https://yzztcl.cn/api/sso/logout" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "Cookie: nova_session=your-session-cookie"
成功响应
{
"success": true,
"message": "退出成功"
}
2.5 生成访问令牌
接口地址: POST /api/sso/token/generate
功能描述: 生成可用于后续验证的访问令牌(需用户已登录)
请求示例
curl -X POST "https://yzztcl.cn/api/sso/token/generate" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "Cookie: nova_session=your-session-cookie"
成功响应
{
"success": true,
"data": {
"token": "eyJ1c2VyX2lkIjoxLCJjbGllbnRfaWQiOiJibG9nLTIwMjQtMDAxIiwiZXhwaXJlX2F0IjoxNzA1Mjk1NjAwLCJub25jZSI6IjE2OTkxMzQwMDAuNjU0MzIxIn0=|d41d8cd98f00b204e9800998ecf8427e",
"user_id": 1,
"expire_at": 1705295600,
"expire_in": 3600
}
}
字段说明
| 字段 | 类型 | 说明 |
|---|---|---|
token |
string | 访问令牌 |
user_id |
int | 用户ID |
expire_at |
int | 过期时间戳 |
expire_in |
int | 有效期(秒) |
2.6 验证访问令牌
接口地址: POST /api/sso/token/verify
功能描述: 验证令牌有效性并获取用户信息
请求头
| 请求头 | 必填 | 说明 |
|---|---|---|
X-Access-Token |
✅ | 访问令牌 |
请求示例
curl -X POST "https://yzztcl.cn/api/sso/token/verify" \ -H "X-Client-Id: your-client-id" \ -H "X-Client-Secret: your-client-secret" \ -H "X-Access-Token: your-access-token"
成功响应
{
"success": true,
"data": {
"user_id": 1,
"username": "admin",
"email": "admin@example.com",
"role": "admin",
"expire_at": 1705295600
}
}
失败响应
{
"success": false,
"message": "无效的令牌"
}
三、权限范围说明
每个客户端可配置不同的权限范围(Scopes):
| Scope | 说明 | 允许的接口 |
|---|---|---|
login_check |
检查登录状态 | /api/sso/check-login |
user_info |
获取用户信息 | /api/sso/user-info |
login |
用户登录 | /api/sso/login |
logout |
用户退出 | /api/sso/logout |
token |
Token操作 | /api/sso/token/* |
注意: 权限范围由管理员在后台配置,未配置的权限将无法访问对应接口。
四、错误码说明
| HTTP状态码 | 错误信息 | 说明 |
|---|---|---|
| 400 | 参数错误 | 请求参数缺失或格式错误 |
| 401 | 未授权的客户端 | 客户端ID或密钥错误 |
| 401 | 用户未登录 | 当前会话未登录 |
| 401 | 无效的Token | Token验证失败 |
| 403 | SSO服务未启用 | 服务未启用 |
| 403 | 权限不足 | 当前客户端没有对应权限 |
| 403 | IP未授权 | 请求IP不在白名单内 |
| 500 | 服务器错误 | 服务端内部错误 |
五、使用示例
5.1 JavaScript 示例
class SsoClient {
constructor(clientId, clientSecret) {
this.clientId = clientId;
this.clientSecret = clientSecret;
this.baseUrl = 'https://yzztcl.cn/api/sso';
}
async request(method, path, data = {}) {
const options = {
method: method.toUpperCase(),
headers: {
'X-Client-Id': this.clientId,
'X-Client-Secret': this.clientSecret,
'Content-Type': 'application/x-www-form-urlencoded'
},
credentials: 'include'
};
if (method.toLowerCase() === 'post') {
options.body = new URLSearchParams(data);
}
const response = await fetch(`${this.baseUrl}${path}`, options);
return response.json();
}
async checkLogin() {
return this.request('get', '/check-login');
}
async getUserInfo() {
return this.request('get', '/user-info');
}
async login(username, password) {
return this.request('post', '/login', { username, password });
}
async logout() {
return this.request('post', '/logout');
}
async generateToken() {
return this.request('post', '/token/generate');
}
async verifyToken(token) {
const options = {
method: 'POST',
headers: {
'X-Client-Id': this.clientId,
'X-Client-Secret': this.clientSecret,
'X-Access-Token': token
}
};
const response = await fetch(`${this.baseUrl}/token/verify`, options);
return response.json();
}
}
// 使用示例
const sso = new SsoClient('your-client-id', 'your-client-secret');
// 登录
const loginResult = await sso.login('admin', 'password');
if (loginResult.success) {
console.log('登录成功:', loginResult.data);
// 获取用户信息
const userInfo = await sso.getUserInfo();
console.log('用户信息:', userInfo.data);
}
5.2 PHP 示例
<?php
class SsoClient {
private $clientId;
private $clientSecret;
private $baseUrl;
public function __construct($clientId, $clientSecret) {
$this->clientId = $clientId;
$this->clientSecret = $clientSecret;
$this->baseUrl = 'https://yzztcl.cn/api/sso';
}
private function request($method, $path, $data = []) {
$url = $this->baseUrl . $path;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-Client-Id: ' . $this->clientId,
'X-Client-Secret: ' . $this->clientSecret
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, '/tmp/sso_cookies.txt');
curl_setopt($ch, CURLOPT_COOKIEFILE, '/tmp/sso_cookies.txt');
if (strtoupper($method) === 'POST') {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
}
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
public function checkLogin() {
return $this->request('GET', '/check-login');
}
public function getUserInfo() {
return $this->request('GET', '/user-info');
}
public function login($username, $password) {
return $this->request('POST', '/login', [
'username' => $username,
'password' => $password
]);
}
public function logout() {
return $this->request('POST', '/logout');
}
public function generateToken() {
return $this->request('POST', '/token/generate');
}
public function verifyToken($token) {
$url = $this->baseUrl . '/token/verify';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-Client-Id: ' . $this->clientId,
'X-Client-Secret: ' . $this->clientSecret,
'X-Access-Token: ' . $token
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
}
// 使用示例
$sso = new SsoClient('your-client-id', 'your-client-secret');
// 登录
$loginResult = $sso->login('admin', 'password');
if ($loginResult['success']) {
echo '登录成功' . PHP_EOL;
// 获取用户信息
$userInfo = $sso->getUserInfo();
print_r($userInfo['data']);
}
?>
5.3 Python 示例
import requests
class SsoClient:
def __init__(self, client_id, client_secret):
self.client_id = client_id
self.client_secret = client_secret
self.base_url = 'https://yzztcl.cn/api/sso'
self.session = requests.Session()
def _request(self, method, path, data=None):
url = f"{self.base_url}{path}"
headers = {
'X-Client-Id': self.client_id,
'X-Client-Secret': self.client_secret
}
if method.upper() == 'GET':
response = self.session.get(url, headers=headers)
else:
response = self.session.post(url, headers=headers, data=data)
return response.json()
def check_login(self):
return self._request('GET', '/check-login')
def get_user_info(self):
return self._request('GET', '/user-info')
def login(self, username, password):
return self._request('POST', '/login', {
'username': username,
'password': password
})
def logout(self):
return self._request('POST', '/logout')
def generate_token(self):
return self._request('POST', '/token/generate')
def verify_token(self, token):
url = f"{self.base_url}/token/verify"
headers = {
'X-Client-Id': self.client_id,
'X-Client-Secret': self.client_secret,
'X-Access-Token': token
}
response = requests.post(url, headers=headers)
return response.json()
# 使用示例
sso = SsoClient('your-client-id', 'your-client-secret')
# 登录
login_result = sso.login('admin', 'password')
if login_result['success']:
print('登录成功')
# 获取用户信息
user_info = sso.get_user_info()
print(user_info['data'])
六、安全注意事项
6.1 密钥管理
- 不要在前端代码中硬编码
client_id和client_secret - 使用环境变量存储敏感信息
- 定期轮换密钥
6.2 传输安全
- 生产环境必须使用 HTTPS
- 避免密钥和Token明文传输
6.3 IP白名单
- 建议配置IP白名单限制访问来源
- 内网系统可限制为内网IP段
6.4 Token安全
- Token有效期默认1小时,可在后台配置
- Token失效后需重新获取
- 退出登录时Token同时失效
七、客户端配置说明
如需接入本SSO鉴权服务,请联系管理员申请客户端凭证。
所需信息
- 系统名称: 您的系统/应用名称
- 系统描述: 简要说明系统用途
- IP白名单: 允许访问的IP地址列表(可选)
- 权限范围: 需要的API权限
配置流程
- 联系管理员提交接入申请
- 管理员创建客户端并分配权限
- 获取
Client ID和Client Secret - 按照文档集成API
- 测试验证接口连通性