# External App(SSO 接入示例) 基于 Next.js 的示例应用,演示如何接入真实 SSO(OAuth2 授权码流程):跳转到 sso-portal 登录 → 在 `/callback` 收到一次性 `sso_code` → 服务端用 code 向后端换 `access_token` 并写入 Cookie 建立会话。 ## 快速开始 ```bash pnpm install pnpm dev # http://localhost:4000 ``` > 需同时启动 [`sso-portal`](../sso-portal)(默认 `http://localhost:5501`)。 > > 📘 **接入文档已移至 sso-portal 仓库**:[`sso-portal/INTEGRATION_GUIDE.md`](../sso-portal/INTEGRATION_GUIDE.md) —— 通用接入指南(前置准备 / OAuth2 流程 / 环境变量 / 安全 / FAQ / 后端接口速查)。本 README 仅为 external-app 项目自身的快速上手。 ## 环境变量 按环境拆分,已随仓库提交(参考 uirefbase 约定):`.env.development` / `.env.staging` / `.env.production`。 本地私有覆盖请写入 `.env*.local`(已被 `.gitignore` 忽略,不入库)。 | 变量 | 端 | 说明 | 示例 | |------|----|------|------| | `NEXT_PUBLIC_SSO_URL` | 客户端 | sso-portal 登录页地址,跳转 `/login` 用 | dev: `http://localhost:5501`
prod: `http://sso-portal-svc:5501` | | `NEXT_PUBLIC_APP_URL` | 客户端 | 本应用地址,作为 SSO 回调 `client_redirect_uri` 传给 sso-portal | `http://localhost:4000` | | `NEXT_PUBLIC_SSO_APP_ID` | 两端 | OAuth2 `client_id`,同时作为 URL `app_id` 传给 sso-portal | `6wds5qua3b76hu748zrjmall` | | `SSO_CLIENT_SECRET` | 服务端 | OAuth2 `client_secret`,`/api/callback` 调 `access_token` 用,**绝不下发前端** | `oXwSxxrRUA0ijJ9N62qWI4oUrVJpLf5F` | | `SSO_BACKEND_API` | 服务端 | 真实后端 SSO 宿主,`/api/callback` 调 `/api/v1/basis/sso/access_token` 用 | dev: `http://172.16.115.31:6610`
prod: `http://basis-app-svc:6610` | | `SSO_TENANT` | 服务端 | 租户标识(SSO 接口的 tenant,与 sso-portal 的 `SSO_TENANT` 一致) | `cowarobot` | > ⚠️ `SSO_CLIENT_SECRET` 含敏感信息,生产建议通过部署平台密钥注入,不入库;本地私有覆盖写入 `.env*.local`(已被 `.gitignore` 忽略)。`.env.production` 中的 `NEXT_PUBLIC_SSO_URL` / `NEXT_PUBLIC_APP_URL` 为占位值,请按实际部署填写。 ## SSO 接入流程 1. 应用跳转到 sso-portal:`{NEXT_PUBLIC_SSO_URL}/login?app_id={NEXT_PUBLIC_SSO_APP_ID}&app_url={NEXT_PUBLIC_APP_URL}/callback` 2. 用户在 sso-portal 登录(账号 / 手机) 3. sso-portal 回跳:`{app_url}?sso_code=xxxxx` 4. 本应用 `/callback` 页把 `sso_code` POST 给 `/api/callback` → 服务端用 `client_secret` 调后端 `/api/v1/basis/sso/access_token` 换 `access_token` → 写入 httpOnly Cookie ## 接口 | 接口 | 方法 | 说明 | |------|------|------| | `/api/callback` | POST | 用 `sso_code` 向后端换 `access_token` 并写 Cookie | | `/api/logout` | POST | 清除会话 Cookie |