- Add portal_auth.go: Portal user session auth with HMAC-signed cookies
- Add /api/portal/session/{login,logout,state} endpoints
- Update nginx config template: cookie-to-header trusted proxy pattern
- Update frontend: sync CRM session on login/logout
- Add TRUSTED_SUBJECT_DEPLOY_GUIDE.md with remote43 deployment steps
- Update EXECUTION_BOARD.md: mark trusted-subject blocking issue as resolved
This implements the secure chain:
Browser → Portal → nginx (cookie→header) → CRM (verify proxy secret)
Required remote43 actions:
1. Generate 64-char hex secret
2. Update .env.crm with TRUSTED_* config
3. Update nginx with cookie map and header injection
4. Restart services
Fixes EXECUTION_BOARD.md 2026-06-08 blocking issue
107 lines
3.5 KiB
Plaintext
107 lines
3.5 KiB
Plaintext
# sub.tksea.top portal routing example
|
||
#
|
||
# 说明:
|
||
# - /portal/ 是新的通用多模型接入中心地址
|
||
# - /kimi-portal 与 /kimi-portal/ 保留 302 跳转,避免旧链接失效
|
||
# - /portal-proxy/ 是页面调用宿主用户态 API 的同域代理
|
||
# - /portal-admin-api/ 是页面调用 CRM 管理 API 的同域代理
|
||
# - /kimi/ 与 /kimi-v1/ 继续保留,兼容旧的 Kimi 专用客户端配置
|
||
#
|
||
# 安全注意事项:
|
||
# - portal-subject 从 cookie 提取,由后端 /api/portal/session/login 设置 httpOnly cookie
|
||
# - CRM 验证 X-CRM-Trusted-Proxy header 确保请求来自受信 nginx
|
||
# - 两者必须同时配置才能启用 user-key self-service
|
||
|
||
# 从 httpOnly cookie 提取 portal subject
|
||
map $http_cookie $portal_subject {
|
||
default "";
|
||
~*crm_session=([^;]+) $1;
|
||
}
|
||
|
||
location = /portal {
|
||
return 302 /portal/;
|
||
}
|
||
|
||
location = /portal/admin {
|
||
return 302 /portal/admin/;
|
||
}
|
||
|
||
location = /kimi-portal {
|
||
return 302 /portal/;
|
||
}
|
||
|
||
# BEGIN sub2api-portal
|
||
location /portal/ {
|
||
alias /var/www/sub2api-portal/;
|
||
index index.html;
|
||
try_files $uri $uri/ /portal/index.html;
|
||
}
|
||
|
||
location /portal-proxy/ {
|
||
proxy_pass http://127.0.0.1:8080/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
location /portal-admin-api/ {
|
||
# 必须由受信登录/鉴权层把用户 subject 放进 $portal_subject,不能信任浏览器自带 header。
|
||
# 同时 CRM 需配置:
|
||
# SUB2API_CRM_TRUSTED_SUBJECT_HEADER=X-CRM-Authenticated-Subject
|
||
# SUB2API_CRM_TRUSTED_PROXY_SECRET_HEADER=X-CRM-Trusted-Proxy
|
||
# SUB2API_CRM_TRUSTED_PROXY_SECRET=<same-secret-as-nginx>
|
||
proxy_pass http://127.0.0.1:18190/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
# 关键:从验证过的 cookie 提取并注入 subject
|
||
proxy_set_header X-CRM-Authenticated-Subject $portal_subject;
|
||
# 受信代理密钥(必须与 CRM 配置一致)
|
||
proxy_set_header X-CRM-Trusted-Proxy "REPLACE_WITH_64_CHAR_HEX_SECRET";
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
location = /v1/chat/completions {
|
||
proxy_pass http://127.0.0.1:18190/v1/chat/completions;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
location /kimi-portal/ {
|
||
return 302 /portal/;
|
||
}
|
||
|
||
location /kimi-portal-proxy/ {
|
||
proxy_pass http://127.0.0.1:8080/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
location /kimi/ {
|
||
proxy_pass http://127.0.0.1:8080/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_http_version 1.1;
|
||
}
|
||
|
||
location /kimi-v1/ {
|
||
proxy_pass http://127.0.0.1:8080/v1/;
|
||
proxy_set_header Host $host;
|
||
proxy_set_header X-Real-IP $remote_addr;
|
||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||
proxy_set_header X-Forwarded-Proto $scheme;
|
||
proxy_http_version 1.1;
|
||
}
|
||
# END sub2api-portal
|