API密钥怎么用?如何配置并验证鉴权?
2个回答
先确认服务的完整测试接口地址和鉴权方式。本例使用NewAPI文档中的GET /v1/models,密钥放在Authorization: Bearer请求头。填写完整接口地址时不要重复拼接/v1,也不要把后台页面的网址当作接口。
下面脚本适用于Linux或macOS的Bash终端,需要可用的curl。密钥通过交互输入,不直接写进命令历史,也不打印到结果中。公开服务使用HTTPS;HTTP只用于本人机器或私有隧道的回环测试。
#!/usr/bin/env bash
# 在当前终端交互输入,不把密钥原文写入命令历史。
read -r -s -p '输入 API 密钥:' API_KEY
printf '\n'
export API_KEY
read -r -p '输入完整测试接口网址(例如 https://服务域名/v1/models):' API_TEST_URL
export API_TEST_URL
# curl 默认不跟随重定向;不要加 --location / -L。
# 请求头经标准输入传给 curl,避免密钥出现在 curl 的命令行参数里。
printf 'Authorization: Bearer %s\n' "$API_KEY" |
curl -q --no-location --globoff --proto '=http,https' --silent --show-error --connect-timeout 5 --max-time 15 \
--output /dev/null --write-out 'HTTP状态码:%{http_code}\n' \
--header @- --url "$API_TEST_URL"
把代码保存为check_api.sh,运行bash check_api.sh,按提示输入你自己的密钥和完整测试网址。Windows用户可在已配置的Bash环境运行,或采用下面的Python方案;不要把Bash的续行符直接粘贴到PowerShell。
怎样判断:本例重点看输出的HTTP状态码:200表示目标返回成功状态,还应确认没有误填成普通网页;下面的Python方案会进一步检查模型列表JSON;401先查密钥、请求头和服务是否匹配;403再查访问范围或网关限制;404核对路径。出现301或302时先核对正确API地址,不要直接加-L把凭据跟着重定向发送。本例用-q忽略个人curl配置,并明确关闭自动跳转。此处curl不使用--fail,进程退出码为0也可能得到401,因此不能只看“命令有没有报错”。
列模型成功只验证了这次鉴权和目录访问,不证明每个模型都能完成推理。终端成功也不代表另一个已运行的应用进程已经读到相同配置。
应用报鉴权失败时,先核对它实际读取的配置名称和启动环境,再验证相同地址。下面的Python标准库示例优先读取当前进程的API_KEY和API_TEST_URL;没有设置时会提示你输入密钥和接口地址。随后向模型列表接口发送GET;不输出密钥、不自动跟随重定向,也不自动继承系统代理。
import json
import getpass
import os
import sys
from urllib.error import HTTPError, URLError
from urllib.parse import urlsplit
from urllib.request import (
HTTPRedirectHandler, ProxyHandler, Request, build_opener
)
try:
key = os.getenv("API_KEY") or getpass.getpass("输入 API 密钥(不回显):")
url = os.getenv("API_TEST_URL") or input("输入完整测试接口网址:").strip()
except (EOFError, KeyboardInterrupt):
sys.exit("输入已取消;自动运行时请先设置 API_KEY 和 API_TEST_URL")
if not key or not url:
sys.exit("缺少 API_KEY 或 API_TEST_URL")
if any(ord(c) < 32 or ord(c) == 127 for c in key):
sys.exit("密钥含有异常换行或控制字符,请重新配置")
try:
parts = urlsplit(url)
port = parts.port
except ValueError:
sys.exit("API_TEST_URL 格式无效")
local_http = (parts.scheme == "http" and
parts.hostname in ("127.0.0.1", "localhost", "::1"))
if (not parts.hostname or parts.username or parts.password or
parts.query or parts.fragment or
(parts.scheme != "https" and not local_http)):
sys.exit("请使用完整 HTTPS 接口地址;HTTP 仅用于本机回环测试")
class NoRedirect(HTTPRedirectHandler):
def redirect_request(self, request, fp, code, msg, headers, newurl):
return None
opener = build_opener(ProxyHandler({}), NoRedirect())
request = Request(url, headers={"Authorization": "Bearer " + key}, method="GET")
try:
with opener.open(request, timeout=15) as response:
raw = response.read(2 * 1024 * 1024 + 1)
if len(raw) > 2 * 1024 * 1024:
sys.exit("响应过大,停止读取")
data = json.loads(raw.decode("utf-8"))
if not isinstance(data, dict) or not isinstance(data.get("data"), list):
sys.exit("返回内容不是预期的模型列表")
print("HTTP {};鉴权请求成功;可见模型数:{}".format(
response.status, len(data["data"])))
except HTTPError as error:
print("HTTP {};请按接口文档检查认证、权限或地址".format(error.code))
sys.exit(1)
except (URLError, TimeoutError):
sys.exit("请求未完成,请检查网络、TLS或超时")
except (UnicodeError, ValueError):
sys.exit("返回内容不是有效的模型列表JSON")
保存为check_api.py,在该文件所在目录运行python check_api.py(若系统使用python3命令,则运行python3 check_api.py),按提示输入密钥和完整接口网址;输入密钥时屏幕不显示字符,输入后按回车即可。无需先学习配置环境变量。已有环境变量时脚本会优先使用,请确认它们属于你要测试的服务。API_TEST_URL使用服务给出的完整https://服务域名/v1/models地址;脚本只为本机回环测试接受HTTP。若服务没有这个端点,先换成其文档中的只读测试接口,并相应调整JSON检查,不能把所有平台当成同一协议。
- 无人值守的容器或系统服务无法等你交互输入,需在实际部署平台配置这两个变量;不要只改个人终端。已经运行的进程通常需要按部署方式重新加载配置。
- 返回200并显示模型数量:本次GET鉴权与模型列表JSON检查通过,不表示任何模型推理请求都已验证。
- 返回401:核对调用密钥是否来自目标服务、是否完整、变量有没有被另一份配置覆盖。
- 返回403或404:分别检查访问范围与完整路径;不要靠无限重试解决。
- 脚本成功、应用失败:对照应用实际的变量名、请求头、URL和运行环境;有些应用读取配置文件或密钥服务,不会自动读取本例变量。
变量名只是这个例子的约定。不要把密钥复制到网页前端、公开仓库或诊断日志;需要排错时只保留已脱敏的状态与配置项名称。