From c8b2129853300113447c8e1dd681950d62babae8 Mon Sep 17 00:00:00 2001 From: nullkey Date: Mon, 11 May 2026 17:37:14 +0800 Subject: [PATCH] docs(api): restore auth.md and update README/wiki links MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #958. - 新建 docs/api/auth.md:覆盖 10 个 /auth/* 端点 register / login / oidc 三件套(config/url/callback)/ refresh / validate / logout / me / change-password。 说明各端点的鉴权方式(无 / refresh_token / Bearer JWT),并对齐 /auth/oidc/callback 的真实行为(始终 302 跳到 / 并把结果编码进 URL hash)。 - docs/api/README.md: - 增加"最权威参考:Swagger UI"段落,引导读者优先访问 /swagger/index.html(swagger 由 swag 注解自动从代码生成)。 - "认证管理"行链接由仅指向 OIDC 流程文档改为同时指向 auth.md 与 OIDC 流程文档。 - 新增 "IM 渠道" 行指向 docs/IM集成开发文档.md。 - 新增 "数据源导入" 行指向 docs/数据源导入开发文档.md。 - docs/wiki/API参考/API文档概览.md:随 api/README.md 的"认证管理" 行同步更新即可——IM 与数据源在该文件原有的"相关主题"/"反向链接" 小节已经登记,不在 "API 分类" 表中重复。 --- docs/api/README.md | 13 +- docs/api/auth.md | 317 +++++++++++++++++++++++++++++++ docs/wiki/API参考/API文档概览.md | 2 +- 3 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 docs/api/auth.md diff --git a/docs/api/README.md b/docs/api/README.md index 73b74c651..ae3fb2605 100644 --- a/docs/api/README.md +++ b/docs/api/README.md @@ -3,6 +3,7 @@ ## 目录 - [概述](#概述) +- [最权威参考:Swagger UI](#最权威参考swagger-ui) - [基础信息](#基础信息) - [认证机制](#认证机制) - [错误处理](#错误处理) @@ -12,6 +13,14 @@ WeKnora 提供了一系列 RESTful API,用于创建和管理知识库、检索知识,以及进行基于知识的问答。本文档详细描述了这些 API 的使用方式。 +## 最权威参考:Swagger UI + +WeKnora 同时提供基于 OpenAPI 的 Swagger 文档。**启动服务后访问 `http://localhost:8080/swagger/index.html`**,可看到所有端点的完整参数、请求/响应 schema,并可直接在浏览器内试调——它随代码自动更新,是最准确的接口参考。 + +本目录下的 markdown 文档提供更易读的示例与场景说明,与 swagger 同步维护;当二者出现差异时,以 swagger 为准。 + +> Swagger UI 仅在非 release 模式(`GIN_MODE != release`)下挂载;生产部署默认关闭。 + ## 基础信息 - **基础 URL**: `/api/v1` @@ -59,7 +68,7 @@ WeKnora API 按功能分为以下几类: | 分类 | 描述 | 文档链接 | |------|------|----------| -| 认证管理 | 用户注册、登录、令牌管理 | [OIDC认证调用流程.md](../OIDC认证调用流程.md) | +| 认证管理 | 用户注册、登录、令牌管理;OIDC 流程 | [auth.md](./auth.md) · [OIDC认证调用流程.md](../OIDC认证调用流程.md) | | 租户管理 | 创建和管理租户账户 | [tenant.md](./tenant.md) | | 知识库管理 | 创建、查询和管理知识库 | [knowledge-base.md](./knowledge-base.md) | | 知识管理 | 上传、检索和管理知识内容 | [knowledge.md](./knowledge.md) | @@ -80,3 +89,5 @@ WeKnora API 按功能分为以下几类: | Skills | 预装智能体技能 | [skill.md](./skill.md) | | 网络搜索 | 网络搜索服务商 | [web-search.md](./web-search.md) | | 向量存储 | 向量数据库连接管理 | [vector-store.md](./vector-store.md) | +| IM 渠道 | 企业微信 / 飞书 / Slack 等 IM 平台对接,含渠道 CRUD 与回调 | [../IM集成开发文档.md](../IM集成开发文档.md) | +| 数据源导入 | 飞书 / 企微 / Notion / Confluence 等外部数据源接入与同步 | [../数据源导入开发文档.md](../数据源导入开发文档.md) | diff --git a/docs/api/auth.md b/docs/api/auth.md new file mode 100644 index 000000000..e0a3da97d --- /dev/null +++ b/docs/api/auth.md @@ -0,0 +1,317 @@ +# 认证管理 API + +[返回目录](./README.md) + +OIDC 完整调用流程见 [../OIDC认证调用流程.md](../OIDC认证调用流程.md)。本文档作为端点参考。 + +## 说明 + +WeKnora 的 `/auth/*` 端点本身**不需要 X-API-Key**,但部分端点需要在 `Authorization: Bearer ` 头中携带由 `/auth/login` 或 `/auth/oidc/callback` 返回的 JWT: + +| 端点 | 鉴权方式 | +| --- | --- | +| `/auth/register` `/auth/login` | 无 | +| `/auth/oidc/config` `/auth/oidc/url` `/auth/oidc/callback` | 无 | +| `/auth/refresh` | refresh_token(请求体携带) | +| `/auth/validate` `/auth/me` `/auth/logout` `/auth/change-password` | Bearer JWT | + +注册接口可通过环境变量 `DISABLE_REGISTRATION=true` 关闭。 + +## 端点一览 + +| 方法 | 路径 | 描述 | +| ---- | -------------------------- | ------------------------------------------ | +| POST | `/auth/register` | 用户注册 | +| POST | `/auth/login` | 用户登录 | +| GET | `/auth/oidc/config` | 获取 OIDC 配置元数据 | +| GET | `/auth/oidc/url` | 获取 OIDC 授权链接 | +| GET | `/auth/oidc/callback` | OIDC 授权回调(由 IdP 重定向触发) | +| POST | `/auth/refresh` | 用 refresh_token 换新的 access_token | +| GET | `/auth/validate` | 验证 JWT 有效性 | +| POST | `/auth/logout` | 退出登录 | +| GET | `/auth/me` | 获取当前用户信息 | +| POST | `/auth/change-password` | 修改密码 | + +--- + +## POST `/auth/register` - 用户注册 + +**参数说明(请求体)**: + +| 字段 | 类型 | 必填 | 校验 | 说明 | +| -------- | ------ | ---- | -------------------------- | --------- | +| username | string | 是 | 长度 2-50 | 用户名 | +| email | string | 是 | 邮箱格式 | 邮箱 | +| password | string | 是 | 最少 6 位 | 密码 | + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/register' \ +--header 'Content-Type: application/json' \ +--data '{ + "username": "alice", + "email": "alice@example.com", + "password": "secret123" +}' +``` + +**响应**(201 Created): + +```json +{ + "success": true, + "message": "Registration successful", + "user": { + "id": "usr-...", + "username": "alice", + "email": "alice@example.com", + "tenant_id": 1, + "is_active": true, + "created_at": "2026-05-11T10:00:00+08:00", + "updated_at": "2026-05-11T10:00:00+08:00" + }, + "tenant": { + "id": 1, + "name": "alice's workspace", + "api_key": "sk-..." + } +} +``` + +**错误**: 注册被禁用 → 403;参数校验失败 → 400。 + +--- + +## POST `/auth/login` - 用户登录 + +**参数说明(请求体)**: + +| 字段 | 类型 | 必填 | 说明 | +| -------- | ------ | ---- | ------------- | +| email | string | 是 | 注册邮箱 | +| password | string | 是 | 密码 | + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/login' \ +--header 'Content-Type: application/json' \ +--data '{ + "email": "alice@example.com", + "password": "secret123" +}' +``` + +**响应**: + +```json +{ + "success": true, + "message": "Login successful", + "user": { "id": "usr-...", "username": "alice", "email": "alice@example.com" }, + "tenant": { "id": 1, "name": "alice's workspace", "api_key": "sk-..." }, + "token": "eyJhbGciOi...", + "refresh_token": "eyJhbGciOi..." +} +``` + +**错误**: 邮箱或密码错误 → 401;账号被禁用 → 403。 + +--- + +## GET `/auth/oidc/config` - 获取 OIDC 配置元数据 + +返回 OIDC 是否启用以及 Provider 显示名,前端登录页据此决定是否展示 OIDC 登录按钮。 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/oidc/config' +``` + +**响应**: + +```json +{ + "success": true, + "enabled": true, + "provider_display_name": "WeKnora SSO" +} +``` + +--- + +## GET `/auth/oidc/url` - 获取 OIDC 授权链接 + +返回前端应跳转的 OIDC IdP 授权页 URL 与状态码。 + +**查询参数**: + +| 字段 | 类型 | 必填 | 说明 | +| ---------- | ------ | ---- | ------------------------------------------------------- | +| redirect | string | 否 | 登录成功后前端期望落地的路径(如 `/dashboard`),透传到 state | + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/oidc/url?redirect=%2Fdashboard' +``` + +**响应**: + +```json +{ + "success": true, + "provider_display_name": "WeKnora SSO", + "authorization_url": "https://idp.example.com/oauth/authorize?client_id=...&state=...", + "state": "abcdef..." +} +``` + +--- + +## GET `/auth/oidc/callback` - OIDC 授权回调 + +由 IdP 在用户授权后重定向到此端点。一般不需要客户端代码直接调用——它的作用是把登录结果通过浏览器 hash 传回前端首页。 + +**查询参数**: + +| 字段 | 类型 | 必填 | 说明 | +| ----------------- | ------ | ---- | ----------------------------- | +| code | string | 是 | IdP 颁发的 authorization code | +| state | string | 是 | 与 `/auth/oidc/url` 返回值一致 | +| error | string | 否 | IdP 返回的错误标识 | +| error_description | string | 否 | IdP 返回的错误详情 | + +**响应**:始终返回 `302 Found`,跳转到 `/`,并把结果编码进 URL hash: + +- 成功:`/#oidc_result=`,其中 payload 包含 `success` / `user` / `tenant` / `token` / `refresh_token` / `is_new_user`,与登录响应一致。 +- 失败:`/#oidc_error=[&oidc_error_description=]`,常见 reason 包括 `invalid_state`、`missing_code`、`login_failed`、`payload_encode_failed`。 + +--- + +## POST `/auth/refresh` - 刷新令牌 + +**参数说明(请求体)**: + +| 字段 | 类型 | 必填 | 说明 | +| ------------- | ------ | ---- | ----------------- | +| refreshToken | string | 是 | 登录时颁发的 refresh_token | + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/refresh' \ +--header 'Content-Type: application/json' \ +--data '{ + "refreshToken": "eyJhbGciOi..." +}' +``` + +**响应**: + +```json +{ + "success": true, + "message": "Token refreshed successfully", + "access_token": "eyJhbGciOi...", + "refresh_token": "eyJhbGciOi..." +} +``` + +**错误**: refresh_token 无效或过期 → 401。 + +--- + +## GET `/auth/validate` - 验证 JWT + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/validate' \ +--header 'Authorization: Bearer eyJhbGciOi...' +``` + +**响应**: + +```json +{ + "success": true, + "valid": true, + "user_id": "usr-...", + "tenant_id": 1 +} +``` + +无效 token 返回 401。 + +--- + +## POST `/auth/logout` - 退出登录 + +**请求**: + +```curl +curl --location --request POST 'http://localhost:8080/api/v1/auth/logout' \ +--header 'Authorization: Bearer eyJhbGciOi...' +``` + +**响应**: `{ "success": true, "message": "Logged out successfully" }` + +--- + +## GET `/auth/me` - 获取当前用户信息 + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/me' \ +--header 'Authorization: Bearer eyJhbGciOi...' +``` + +**响应**: + +```json +{ + "success": true, + "user": { + "id": "usr-...", + "username": "alice", + "email": "alice@example.com", + "avatar": "", + "tenant_id": 1, + "is_active": true, + "can_access_all_tenants": false, + "created_at": "2026-05-11T10:00:00+08:00", + "updated_at": "2026-05-11T10:00:00+08:00" + } +} +``` + +--- + +## POST `/auth/change-password` - 修改密码 + +**参数说明(请求体)**: + +| 字段 | 类型 | 必填 | 校验 | 说明 | +| ------------- | ------ | ---- | ------- | --------- | +| old_password | string | 是 | | 旧密码 | +| new_password | string | 是 | 最少 6 位 | 新密码 | + +**请求**: + +```curl +curl --location 'http://localhost:8080/api/v1/auth/change-password' \ +--header 'Authorization: Bearer eyJhbGciOi...' \ +--header 'Content-Type: application/json' \ +--data '{ + "old_password": "secret123", + "new_password": "newsecret456" +}' +``` + +**响应**: `{ "success": true, "message": "Password changed successfully" }` + +**错误**: 旧密码不匹配或新密码不满足校验 → 400。 diff --git a/docs/wiki/API参考/API文档概览.md b/docs/wiki/API参考/API文档概览.md index aa17f3d45..3db840853 100644 --- a/docs/wiki/API参考/API文档概览.md +++ b/docs/wiki/API参考/API文档概览.md @@ -45,7 +45,7 @@ API Key 在 Web 页面完成账户注册后,前往账户信息页面获取。 | 分类 | 描述 | 详细文档 | |------|------|----------| -| 认证管理 | 用户注册、登录、令牌管理 | [OIDC认证调用流程.md](../安全认证/OIDC认证调用流程.md) | +| 认证管理 | 用户注册、登录、令牌管理;OIDC 流程 | [auth.md](../../api/auth.md) · [OIDC认证调用流程.md](../安全认证/OIDC认证调用流程.md) | | 租户管理 | 创建和管理租户账户 | [tenant.md](../../api/tenant.md) | | 知识库管理 | 创建、查询和管理知识库 | [knowledge-base.md](../../api/knowledge-base.md) | | 知识管理 | 上传、检索和管理知识内容 | [knowledge.md](../../api/knowledge.md) |