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

如何用Python通过Google OAuth的code获取令牌(React+Python授权流)

用Python处理Google OAuth授权码换取令牌(适配React前端)

核心依赖

使用官方的google-auth-oauthlib库处理OAuth流程,搭配常用Web框架实现后端接口。先安装依赖:

pip install google-auth-oauthlib flask  # Flask版本
# 或者FastAPI版本:pip install google-auth-oauthlib fastapi uvicorn

Flask后端实现示例

from flask import Flask, request, jsonify
from google_auth_oauthlib.flow import Flow
import os

app = Flask(__name__)

# 开发环境临时允许HTTP传输(生产环境必须用HTTPS,删除此行)
os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

# Google OAuth配置(和前端React的配置保持一致)
CLIENT_CONFIG = {
    "web": {
        "client_id": "你的Google客户端ID",
        "client_secret": "你的Google客户端密钥",
        "redirect_uris": ["前端授权完成后的重定向URI"],
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token"
    }
}

@app.route('/api/google/exchange-token', methods=['POST'])
def exchange_token():
    # 接收前端传来的授权code
    code = request.json.get('code')
    if not code:
        return jsonify({'error': '缺少授权码code'}), 400
    
    try:
        # 初始化OAuth Flow
        flow = Flow.from_client_config(
            CLIENT_CONFIG,
            scopes=['openid', 'email', 'profile']  # 必须和前端请求的scope完全匹配
        )
        flow.redirect_uri = CLIENT_CONFIG['web']['redirect_uris'][0]
        
        # 用code换取令牌(对应Node.js的oAuth2Client.getToken方法)
        credentials = flow.fetch_token(code=code)
        
        # 整理返回给前端的令牌数据
        tokens = {
            'access_token': credentials.token,
            'refresh_token': credentials.refresh_token,
            'expires_at': credentials.expiry.timestamp()
        }
        
        return jsonify(tokens), 200
    except Exception as e:
        return jsonify({'error': str(e)}), 500

if __name__ == '__main__':
    app.run(debug=True)

FastAPI后端实现示例

如果用FastAPI,代码结构类似:

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from google_auth_oauthlib.flow import Flow
import os

app = FastAPI()

os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
CLIENT_CONFIG = {
    "web": {
        "client_id": "你的Google客户端ID",
        "client_secret": "你的Google客户端密钥",
        "redirect_uris": ["前端授权完成后的重定向URI"],
        "auth_uri": "https://accounts.google.com/o/oauth2/auth",
        "token_uri": "https://oauth2.googleapis.com/token"
    }
}

# 定义请求体结构
class TokenRequest(BaseModel):
    code: str

@app.post('/api/google/exchange-token')
async def exchange_token(req: TokenRequest):
    if not req.code:
        raise HTTPException(status_code=400, detail='缺少授权码code')
    
    try:
        flow = Flow.from_client_config(
            CLIENT_CONFIG,
            scopes=['openid', 'email', 'profile']
        )
        flow.redirect_uri = CLIENT_CONFIG['web']['redirect_uris'][0]
        credentials = flow.fetch_token(code=req.code)
        
        return {
            'access_token': credentials.token,
            'refresh_token': credentials.refresh_token,
            'expires_at': credentials.expiry.timestamp()
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

关键注意事项

  • Scope匹配:后端配置的scopes必须和前端React发起授权请求时的scope完全一致,否则会导致令牌交换失败。
  • 生产环境配置:删除OAUTHLIB_INSECURE_TRANSPORT的设置,强制使用HTTPS;客户端ID和密钥不要硬编码,用环境变量(比如os.getenv('GOOGLE_CLIENT_ID'))读取。
  • 前端调用:React端获取到授权code后,通过POST请求将code发送到上述后端接口,即可拿到令牌,逻辑和Node.js版本一致。

内容的提问来源于stack exchange,提问作者Arseniy-II

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 21:08:14