身份验证:API 密钥与 OAuth
用于代理 API 访问的持有者令牌、API 密钥请求头和 OAuth2 流程。
身份验证:API 密钥与 OAuth 是 CoddyKit 上的免费 AI Agents 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Agents 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Agents 课程共包含 4 节课。
为什么身份验证对智能体很重要
当您的智能体调用外部 API 时,服务器需要知道请求是由谁发出的。身份验证用于证明身份;授权决定您可以执行哪些操作。如果没有正确的身份验证,每个请求都会返回 401 Unauthorized,您的智能体将无法执行任何操作。
智能体开发中最常见的两种模式是:API 密钥和 OAuth 2.0。
import requests
# Without auth — will get 401
response = requests.get('https://api.openai.com/v1/models')
print(response.status_code) # 401 Unauthorized
# With API key in header — works
headers = {'Authorization': 'Bearer sk-proj-abc123'}
response = requests.get(
'https://api.openai.com/v1/models',
headers=headers
)
print(response.status_code) # 200Authorization 标头中的 API 密钥
最常见的模式是将 API 密钥作为持有者令牌放入 Authorization 标头中。“Bearer”一词表示持有此令牌的任何人都已获得授权——服务器信任密钥的持有者。
OpenAI、Anthropic、GitHub 以及大多数现代 API 都采用这种方式。
import requests
import os
api_key = os.environ['OPENAI_API_KEY']
response = requests.post(
'https://api.openai.com/v1/chat/completions',
headers={
'Authorization': f'Bearer {api_key}',
'Content-Type': 'application/json'
},
json={
'model': 'gpt-4o-mini',
'messages': [{'role': 'user', 'content': 'Hello!'}]
}
)
print(response.json()['choices'][0]['message']['content'])自定义标头中的 API 密钥(X-API-Key)
有些 API——尤其是较旧的 API 或内部 API——会使用类似 X-API-Key 的自定义标头,而不是 Authorization: Bearer。模式相同,只是标头名称不同。请始终查阅 API 文档,确认所需的准确标头名称。
import requests
import os
api_key = os.environ['SERVICE_API_KEY']
response = requests.get(
'https://api.someservice.com/v1/data',
headers={
'X-API-Key': api_key,
'Accept': 'application/json'
}
)
if response.status_code == 200:
data = response.json()
print('Got data:', data)
elif response.status_code == 401:
print('Invalid API key — check X-API-Key header')将凭据存储在环境变量中
绝不要将 API 密钥硬编码在源代码中。如果您将密钥提交到公共代码仓库,机器人会在几秒内找到并滥用它。正确的做法是将凭据存储在环境变量中,并在运行时使用 os.environ 读取。
如果密钥缺失,请使用 os.environ.get() 并提供清晰的错误消息。
import os
os.environ['OPENAI_API_KEY'] = 'sk-proj-abc123xyz789' # simulate a set env var
api_key = os.environ.get('OPENAI_API_KEY')
if not api_key:
raise EnvironmentError(
'OPENAI_API_KEY environment variable not set. '
'Run: export OPENAI_API_KEY=your-key-here'
)
print('API key loaded from environment (never hard-code it in source)')使用 python-dotenv 进行本地开发
在开发期间,请将密钥保存在项目根目录下的 .env 文件中。使用 python-dotenv 库自动加载这些密钥。将 .env 添加到 .gitignore 中,确保它永远不会被提交。
# .env file (never commit this!)
# OPENAI_API_KEY=sk-proj-abc123
# ANTHROPIC_API_KEY=sk-ant-xyz456
# GITHUB_TOKEN=ghp_abc789
# In your Python code:
from dotenv import load_dotenv
import os
load_dotenv() # loads .env into os.environ
openai_key = os.environ['OPENAI_API_KEY']
anthropic_key = os.environ['ANTHROPIC_API_KEY']
github_token = os.environ['GITHUB_TOKEN']
print('Keys loaded successfully')什么是 OAuth 2.0
OAuth 2.0 是一种委托授权标准。OAuth 不要求您将用户密码交给智能体,而是让用户授权您的智能体代表其行事,并限制授权范围和有效时间。Google、GitHub、Slack 和 Salesforce 都在使用它。
关键概念是:您的智能体在完成授权流程后会获得一个访问令牌,然后使用该令牌调用 API。
# OAuth flow overview:
#
# 1. Agent redirects user to:
# https://auth.provider.com/oauth/authorize
# ?client_id=YOUR_CLIENT_ID
# &redirect_uri=http://localhost:8080/callback
# &scope=read:repo%20write:issues
# &response_type=code
#
# 2. User logs in and grants permission
# 3. Provider redirects to your callback with ?code=AUTH_CODE
# 4. Agent exchanges code for access_token
# 5. Agent uses access_token for API calls
print('OAuth flow: authorize -> code -> token -> API calls')OAuth2 客户端凭据流程
客户端凭据流程是面向代理的最简单 OAuth 流程——无需用户交互。您的代理使用自己的客户端 ID 和密钥进行身份验证,以获取令牌。这用于机器对机器(M2M)通信。
您将凭据 POST 到令牌端点,并接收一个短期访问令牌。
import requests
import os
client_id = os.environ['OAUTH_CLIENT_ID']
client_secret = os.environ['OAUTH_CLIENT_SECRET']
token_url = 'https://auth.example.com/oauth/token'
# Request an access token
response = requests.post(token_url, data={
'grant_type': 'client_credentials',
'client_id': client_id,
'client_secret': client_secret,
'scope': 'read:data write:tasks'
})
token_data = response.json()
access_token = token_data['access_token']
expires_in = token_data['expires_in'] # seconds
print(f'Token valid for {expires_in}s')在 API 调用中使用 OAuth 令牌
获取 OAuth 访问令牌后,请像使用 API 密钥一样使用它——将其放在 Authorization: Bearer 标头中。不同之处在于,OAuth 令牌会过期,因此您的代理必须在发起调用前处理令牌刷新。
import requests
import os
import time
class OAuthClient:
def __init__(self, client_id, client_secret, token_url):
self.client_id = client_id
self.client_secret = client_secret
self.token_url = token_url
self.access_token = None
self.token_expiry = 0
def get_token(self):
if time.time() < self.token_expiry - 60: # 60s buffer
return self.access_token
r = requests.post(self.token_url, data={
'grant_type': 'client_credentials',
'client_id': self.client_id,
'client_secret': self.client_secret
})
data = r.json()
self.access_token = data['access_token']
self.token_expiry = time.time() + data['expires_in']
return self.access_token
def get(self, url):
token = self.get_token()
return requests.get(url, headers={'Authorization': f'Bearer {token}'})使用 google-auth 库实现 OAuth 2.0
对于 Google API,google-auth 库会为您处理所有 OAuth 复杂性。它会自动管理令牌刷新,从 JSON 文件中读取凭据,并通过 AuthorizedSession 将令牌附加到请求中。
from google.oauth2 import service_account
from google.auth.transport.requests import AuthorizedSession
# Load service account credentials from JSON file
credentials = service_account.Credentials.from_service_account_file(
'service-account.json',
scopes=[
'https://www.googleapis.com/auth/gmail.readonly',
'https://www.googleapis.com/auth/calendar.events'
]
)
# AuthorizedSession auto-refreshes tokens
session = AuthorizedSession(credentials)
response = session.get(
'https://www.googleapis.com/gmail/v1/users/me/messages'
)
print(response.json())API 密钥安全最佳实践
保护 API 密钥对代理安全至关重要。请遵循以下规则:
- 将密钥存储在环境变量或密钥管理器中(AWS Secrets Manager、HashiCorp Vault)
- 绝不要记录密钥日志——在输出中将其掩码
- 定期轮换密钥,并立即撤销已泄露的密钥
- 遵循最小权限原则——只请求代理所需的权限范围
- 如果服务提供商支持,请为 API 密钥设置 IP 允许列表
import os
os.environ['OPENAI_API_KEY'] = 'sk-proj-abc123xyz789'
def get_key(env_var):
key = os.environ.get(env_var)
if not key:
raise EnvironmentError(f'Missing required env var: {env_var}')
return key
def mask_key(key):
if len(key) < 8:
return '***'
return key[:4] + '...' + key[-4:]
api_key = get_key('OPENAI_API_KEY')
print(f'Using key: {mask_key(api_key)}')在您的代理中处理 401 未授权
当代理收到 401 Unauthorized 响应时,绝不要盲目重试——这会浪费速率限制配额。相反,请检查令牌是否已过期(尝试刷新),或者密钥本身是否无效(立即发出警报,以便人工修复)。
import requests
import os
def call_api_with_auth_check(url, api_key):
response = requests.get(
url,
headers={'Authorization': f'Bearer {api_key}'}
)
if response.status_code == 401:
error = response.json().get('error', {})
code = error.get('code', 'unknown')
if code == 'token_expired':
print('Token expired — refresh needed')
# trigger token refresh flow
else:
raise PermissionError(
f'API key rejected: {error.get("message", "401 Unauthorized")}'
)
response.raise_for_status()
return response.json()快速检查:API 密钥存储
测试您对凭据管理的理解。
身份验证回顾
您已经了解了代理使用的两种主要身份验证模式:
- API 密钥——通过
Authorization: Bearer TOKEN或X-API-Key标头传递;简单且无状态 - OAuth 2.0——用于 M2M 的客户端凭据流程;令牌会过期,必须刷新
- 始终将密钥存储在环境变量中,绝不要存放在源代码里
- 在本地使用 python-dotenv;在生产环境中使用环境变量或密钥管理器
- 处理 401 响应时,检查令牌是否过期,而不是直接判断密钥无效
稳健的身份验证处理是每个可靠代理的基础。
常见问题解答
「身份验证:API 密钥与 OAuth」课时是免费的吗?
是的 — 「身份验证:API 密钥与 OAuth」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Agents 课程的其余内容,请升级到 CoddyKit PRO。 AI Agents 课程共包含 4 节课。
「身份验证:API 密钥与 OAuth」这节课中我会学到什么?
用于代理 API 访问的持有者令牌、API 密钥请求头和 OAuth2 流程。 你通过在浏览器中直接运行的动手代码来练习 AI Agents,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 AI Agents 需要有经验吗?
无需任何先前经验。CoddyKit 上的 AI Agents 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「身份验证:API 密钥与 OAuth」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 AI Agents 课中编写并运行代码吗?
能。每节 AI Agents 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- 代理开发者的 REST API 基础
- 身份验证:API 密钥与 OAuth
- 处理 API 响应与错误
- 速率限制与重试逻辑