已创建谷歌云客户端ID,如何在Pyramid框架对接Google OAuth?
1. 安装依赖包
你需要先安装OAuth通信、会话存储相关的第三方库,执行命令:pip install pyramid requests-oauthlib pyramid-beaker
2. 配置项目参数
在项目的.ini配置文件(比如development.ini)中添加Google OAuth相关配置和会话配置:
Google OAuth配置google_oauth2.client_id = 你之前在Google Cloud控制台创建的Client ID
google_oauth2.client_secret = 你之前在Google Cloud控制台创建的Secret ID
google_oauth2.scope = openid email profile
google_oauth2.redirect_uri = 你在Google Cloud控制台配置的授权回调地址(示例:http://localhost:6543/google/callback)Beaker会话配置beaker.session.type = file
beaker.session.data_dir = %(here)s/data/sessions/data
beaker.session.lock_dir = %(here)s/data/sessions/lock
beaker.session.secret = 自定义的随机加密字符串
beaker.session.cookie_on_exception = True
3. 初始化OAuth客户端
修改项目入口文件(一般是__init__.py的main函数),注册会话支持和OAuth客户端到请求对象:
from pyramid.config import Configurator from requests_oauthlib import OAuth2Session def main(global_config, **settings): config = Configurator(settings=settings) # 注册Beaker会话支持 config.include('pyramid_beaker') # 将OAuth客户端绑定到请求对象,每次请求自动生成实例 def get_google_oauth(request): client_id = request.registry.settings['google_oauth2.client_id'] redirect_uri = request.registry.settings['google_oauth2.redirect_uri'] scope = request.registry.settings['google_oauth2.scope'].split() return OAuth2Session(client_id, redirect_uri=redirect_uri, scope=scope) config.add_request_method(get_google_oauth, 'google_oauth', reify=True) # 注册后续要用到的路由 config.add_route('google_login', '/google/login') config.add_route('google_callback', '/google/callback') config.scan() return config.make_wsgi_app()
4. 实现授权跳转视图
添加登录跳转逻辑,用户访问该路由时会自动跳转到Google的授权页面:
from pyramid.view import view_config from pyramid.httpexceptions import HTTPFound, HTTPBadRequest @view_config(route_name='google_login') def google_login(request): auth_base_url = 'https://accounts.google.com/o/oauth2/v2/auth' auth_url, state = request.google_oauth.authorization_url( auth_base_url, access_type='offline', prompt='select_account' ) # 将state存入会话用于后续回调校验,防止CSRF攻击 request.session['oauth_state'] = state return HTTPFound(location=auth_url)
5. 实现授权回调视图
Google校验通过后会回调你配置的回调地址,在该视图中完成token换取和用户信息获取:
@view_config(route_name='google_callback') def google_callback(request): token_url = 'https://www.googleapis.com/oauth2/v4/token' client_secret = request.registry.settings['google_oauth2.client_secret'] # 校验state参数合法性 saved_state = request.session.pop('oauth_state', None) current_state = request.params.get('state') if not saved_state or saved_state != current_state: return HTTPBadRequest('非法请求,状态校验不通过') # 用授权码换取access token token = request.google_oauth.fetch_token( token_url, client_secret=client_secret, authorization_response=request.url ) # 用access token获取用户公开信息 user_info = request.google_oauth.get('https://www.googleapis.com/oauth2/v3/userinfo').json() # 此处可添加你的业务逻辑:比如查询用户是否存在、创建用户、写入登录态等 request.session['logged_user'] = user_info # 回调完成后跳转到首页或用户之前访问的页面 return HTTPFound(location='/')
6. 登录态校验
在需要登录才能访问的视图中,判断会话中是否存在logged_user字段,不存在则跳转到授权登录路由即可。
注意:开发环境使用http协议时,需要提前设置环境变量
OAUTHLIB_INSECURE_TRANSPORT=1绕过OAuth的HTTPS校验;生产环境必须使用HTTPS,否则Google会拒绝回调请求。
内容的提问来源于stack exchange,提问作者P Pariventhan

