You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用requests发起GET授权请求如何获取回调授权码

问题根因

当前实现逻辑存在本质错误:

  • requests 库发起的HTTP请求和webbrowser唤起的系统浏览器是完全独立的两个HTTP客户端,你预先用requests.get拿到的只是授权端点的初始构造URL,授权完成后的302跳转动作完全发生在浏览器侧,你的Python程序既没有参与这个跳转流程,也没有监听对应重定向地址的端口,自然拿不到返回内容。
  • 授权码是携带在跳转后URL的query参数中,并非藏在初始授权接口的响应体里,你最开始调用requests.get的逻辑本身就是多余的。
实现方案

OAuth2授权码模式的本地回调核心逻辑非常简单:在本地启动一个临时HTTP服务,监听你在开放平台预先配置的重定向URI对应的端口和路径,等用户完成授权、浏览器自动跳转到这个本地地址时,直接从请求的query参数里解析出code字段即可,不需要额外部署公网回调服务。

具体步骤

  • 先去应用的开放平台配置页,把重定向URL设置为本地地址,比如 http://localhost:8888/callback,端口选一个没被占用的即可,路径只要和后续监听的路径保持一致就行。
  • 不需要提前用requests请求授权端点,直接拼接好带业务参数的授权URL,交给浏览器打开即可。
  • 在唤起浏览器之前,先启动本地临时HTTP服务阻塞等待回调,解析到授权码之后立刻关闭临时服务,继续执行后续换token的业务逻辑。

参考实现代码

直接用Python标准库就能实现,不需要安装额外第三方依赖:

import webbrowser
import requests
from http.server import BaseHTTPRequestHandler, HTTPServer
from urllib.parse import urlparse, parse_qs

# 替换成你自己的应用配置
CLIENT_ID = "你的应用客户端ID"
CLIENT_SECRET = "你的应用客户端密钥"
AUTH_ENDPOINT = "平台授权接口地址"
TOKEN_ENDPOINT = "平台token换取接口地址"
REDIRECT_URI = "http://localhost:8888/callback"
SCOPE = "你需要申请的权限范围"
LISTEN_PORT = 8888

auth_code = None

class CallbackHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        global auth_code
        # 解析回调请求的参数
        query_params = parse_qs(urlparse(self.path).query)
        if 'code' in query_params:
            auth_code = query_params['code'][0]
            # 给浏览器返回授权成功提示
            self.send_response(200)
            self.send_header('Content-Type', 'text/html; charset=utf-8')
            self.end_headers()
            self.wfile.write(b"<h3>授权成功,可关闭当前页面返回程序</h3>")
        else:
            self.send_response(400)
            self.end_headers()
            self.wfile.write(b"授权失败,未获取到有效授权码")
        # 处理完回调立刻关闭临时服务
        self.server.shutdown()

    # 屏蔽HTTP服务默认的控制台日志输出,不需要可以删掉这段
    def log_message(self, format, *args):
        return

if __name__ == "__main__":
    # 构造授权访问URL
    auth_query = {
        "response_type": "code",
        "client_id": CLIENT_ID,
        "redirect_uri": REDIRECT_URI,
        "scope": SCOPE
        # 生产环境请增加state参数做CSRF校验,这里做简化省略
    }
    auth_url = requests.Request("GET", AUTH_ENDPOINT, params=auth_query).prepare().url

    # 启动本地临时监听服务
    local_server = HTTPServer(("0.0.0.0", LISTEN_PORT), CallbackHandler)
    # 打开系统浏览器跳转到授权页
    webbrowser.open(auth_url, new=0, autoraise=True)
    # 阻塞等待回调请求
    local_server.serve_forever()

    # 走到这里已经拿到授权码,可继续执行换取access_token逻辑
    print(f"获取到的授权码:{auth_code}")
    token_query = {
        "grant_type": "authorization_code",
        "code": auth_code,
        "redirect_uri": REDIRECT_URI,
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET
    }
    token_resp = requests.post(TOKEN_ENDPOINT, data=token_query).json()
    print("换取到的凭证信息:", token_resp)

注意事项

  • 如果对接的平台不允许使用localhost作为重定向地址,强制要求HTTPS公网回调地址,要么单独部署公网服务接收回调请求,要么改用平台支持的其他授权模式(比如设备码模式),不要硬改本地逻辑。
  • 正式环境必须加state参数校验:发起授权时生成随机字符串存在本地,回调时比对请求带回的state值和本地存储的是否一致,避免CSRF攻击。
  • 启动临时服务前要确认监听端口没有被其他程序占用,否则会启动失败。

内容的提问来源于stack exchange,提问作者gemaltemusik

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 04:18:16