Files
holy-python/skills/holy-crab/scripts/get-cookie.sh
2026-08-04 14:02:45 +08:00

217 lines
8.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# get-cookie.sh — Holy Crab AI 认证流程
#
# 流程:
# 1. 从后端获取钉钉授权 URL
# 2. 让用户在浏览器打开,授权后 URL 里会带 authCode
# 3. AI 把 authCode 贴过来 → 调用 /api/v1/auth/direct-token 换出 session token
# 4. 存 token 到 ~/.holy_crab_env后续所有请求自动带 Cookie
#
# 用法:
# bash get-cookie.sh # 交互式
# bash get-cookie.sh --check # 仅检查 token 是否有效
# bash get-cookie.sh <authCode> # 直接用 authCode 换 token
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
SKILL_DIR="$(dirname "$SCRIPT_DIR")"
COOKIE_FILE="$HOME/.holy_crab_cookie"
ENV_FILE="$HOME/.holy_crab_env"
BACKEND="${HC_BACKEND_URL:-http://localhost:8000}"
# ---------------------------------------------------------------------------
# 工具函数
# ---------------------------------------------------------------------------
save_token() {
local token="$1"
echo "HC_SESSION=${token}" > "$ENV_FILE"
chmod 600 "$ENV_FILE"
echo "✅ Token 已写入: $ENV_FILE"
echo ""
echo "📋 后续 AI 将自动从此文件读取 Cookie无需任何额外操作。"
}
save_token_raw() {
local token="$1"
echo "$token" > "$COOKIE_FILE"
chmod 600 "$COOKIE_FILE"
}
check_token() {
local token="$1"
local http_code
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
--max-time 10 \
-H "Cookie: hc_session=${token}" \
"$BACKEND/api/v1/auth/me")
if [ "$http_code" = "200" ]; then
echo "✅ Token 有效"
return 0
else
echo "❌ Token 无效或已过期 (HTTP $http_code)"
return 1
fi
}
# 从现有文件读 token
load_existing_token() {
# 优先 ~/.holy_crab_env
if [ -f "$ENV_FILE" ]; then
local val
val=$(grep -E "^HC_SESSION=" "$ENV_FILE" 2>/dev/null | head -1 | cut -d= -f2- | tr -d '"' | tr -d "'" | xargs)
[ -n "$val" ] && echo "$val" && return 0
fi
# 兜底 ~/.holy_crab_cookie
if [ -f "$COOKIE_FILE" ]; then
local val
val=$(cat "$COOKIE_FILE" | xargs)
[ -n "$val" ] && echo "$val" && return 0
fi
return 1
}
# ---------------------------------------------------------------------------
# Step 1检查现有 token
# ---------------------------------------------------------------------------
if [ "$1" = "--check" ]; then
echo ""
echo "🔍 检查现有 Token..."
if EXISTING=$(load_existing_token 2>/dev/null); then
if check_token "$EXISTING"; then
echo ""
echo " Token 来自: ${ENV_FILE:-$COOKIE_FILE}"
exit 0
fi
fi
echo " 未找到有效 Token需要重新授权。"
exit 1
fi
# ---------------------------------------------------------------------------
# Step 2直接用 authCode 换 token
# ---------------------------------------------------------------------------
if [ -n "$1" ] && [ "$1" != "--check" ]; then
AUTH_CODE="$1"
echo ""
echo "🔄 正在用 authCode 换取 session token..."
RESPONSE=$(curl -s --max-time 20 \
"$BACKEND/api/v1/auth/direct-token?authCode=${AUTH_CODE}")
ERROR=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('code',''))" 2>/dev/null)
if [ -n "$ERROR" ]; then
MSG=$(echo "$RESPONSE" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('msg',''))" 2>/dev/null)
echo "❌ 换取失败: [$ERROR] $MSG"
echo " 原始响应: $RESPONSE"
exit 1
fi
TOKEN=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['token'])" 2>/dev/null)
USER=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['user'].get('name','?'))" 2>/dev/null)
EXPIRES=$(echo "$RESPONSE" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['expires_at'])" 2>/dev/null)
if [ -z "$TOKEN" ]; then
echo "❌ 响应解析失败,原始响应:"
echo "$RESPONSE"
exit 1
fi
echo "✅ 换取成功!"
echo " 用户:$USER"
echo " 有效期至:$EXPIRES"
save_token "$TOKEN"
echo ""
echo "🎉 认证完成AI 现在可以访问 Holy Crab 后端了!"
exit 0
fi
# ---------------------------------------------------------------------------
# Step 3交互式引导 — 获取 authCode
# ---------------------------------------------------------------------------
echo ""
echo "═══════════════════════════════════════════════════════"
echo " 🔐 Holy Crab · AI 授权流程"
echo "═══════════════════════════════════════════════════════"
echo ""
echo " 本流程分两步:① 获取授权码 ② 换取 Token"
echo ""
# 检查后端是否可达
if ! curl -s --max-time 5 "$BACKEND/health" > /dev/null 2>&1; then
echo " ❌ 后端不可达: $BACKEND"
echo ""
echo " 请确认:"
echo " 1. 后端是否已启动python3 app.py"
echo " 2. HC_BACKEND_URL 是否正确?"
echo ""
echo " 当前 BACKEND=$BACKEND"
echo " 修改方式export HC_BACKEND_URL=http://服务器IP:8000"
exit 1
fi
echo " ✅ 后端在线: $BACKEND"
# 检查现有 token
if EXISTING=$(load_existing_token 2>/dev/null); then
if check_token "$EXISTING"; then
echo ""
echo " ✅ 已有有效 Token无需重新授权。"
echo " Token 来源: ${ENV_FILE:-$COOKIE_FILE}"
exit 0
else
echo " ⚠️ 已有 Token 但已过期,需要重新授权..."
fi
fi
echo ""
echo "───────────────────────────────────────────────────────"
echo " Step 1在浏览器中完成钉钉授权"
echo "───────────────────────────────────────────────────────"
echo ""
# 获取钉钉授权 URL
AUTH_URL_RESP=$(curl -s --max-time 10 "$BACKEND/api/v1/auth/dingtalk/login?redirect=/")
AUTH_URL=$(echo "$AUTH_URL_RESP" | python3 -c "import sys,json; print(json.load(sys.stdin)['data']['url'])" 2>/dev/null)
if [ -z "$AUTH_URL" ]; then
echo " ❌ 无法获取钉钉授权 URL后端可能未配置 DINGTALK_CLIENT_ID"
echo " 原始响应: $AUTH_URL_RESP"
exit 1
fi
echo " 请在浏览器中打开以下链接:"
echo ""
echo " $AUTH_URL"
echo ""
echo " 操作步骤:"
echo " 1. 浏览器会自动打开钉钉授权页面"
echo " 2. 点击「授权登录」"
echo " 3. 授权成功后,浏览器会跳转到后端页面"
echo " 4. 此时地址栏 URL 中会有 ?authCode=xxxxx"
echo " 把 authCode= 后面的那串字符复制下来"
echo ""
# 自动打开浏览器
if command -v open >/dev/null 2>&1; then
echo " 正在打开授权页面..."
open "$AUTH_URL" 2>/dev/null || true
fi
echo ""
echo "───────────────────────────────────────────────────────"
echo " Step 2把 authCode 贴过来"
echo "───────────────────────────────────────────────────────"
echo ""
echo " 复制 authCode 后,运行以下命令(把 YOUR_AUTH_CODE 换成你的值):"
echo ""
echo " bash $0 YOUR_AUTH_CODE"
echo ""
echo " 或者直接告诉 AI"
echo " 【authCode】YOUR_AUTH_CODE"
echo " AI 会自动帮你完成后续操作。"
echo ""
echo "═══════════════════════════════════════════════════════"