如何用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
相关产品推荐
相关产品推荐

