如何解决如何在授权代码授予流程OAuth 2中将数据从主要API传递到重定向的API?
我正在使用Authlib的Flask OAuth客户端编写用于授权代码授予范例的OAuth客户端应用程序。该应用程序分为两个API
- AutoEmail-从前端React应用程序调用,如果访问令牌可用于数据库中的用户,则代表用户发送电子邮件,或触发Gmail授权URL。
- 授权-从授权服务器回叫的重定向URL的端点。触发后,请求访问令牌,插入到DB,然后发送电子邮件。
要使第二个API起作用,它需要从前端收到的用户电子邮件。我需要电子邮件
- 弄清楚服务名称-google / outlook,以便我可以用它来创建客户端
client = oauth.create_client(service_name)
- 运行验证。
这是代码
from flask import Blueprint,request,make_response,jsonify,url_for,session
from flask.views import MethodView
from authlib.integrations.flask_client import OAuth
from application import app,db
from application.utils.auth import verify_token
from application.models import OAuthToken
from .helper import *
from .constants import *
oauth_blueprint = Blueprint('oauth',__name__)
def register_oauth(service_config):
oauth = OAuth(app,update_token=update_token)
client = oauth.register(
name=service_config['NAME'],client_id=service_config['CLIENT_ID'],client_secret=service_config['CLIENT_SECRET'],access_token_url=service_config['ACCESS_TOKEN_URL'],authorize_url=service_config['AUTHORIZE_URL'],authorize_params=service_config['AUTHORIZE_ParaMS'],api_base_url=service_config['API_BASE_URL'],client_kwargs=service_config['CLIENT_kwargs']
)
return client
class AutoEmail(MethodView):
def get(self):
user_email = request.args.get('user_id')
token = OAuthToken.query.filter_by(user_email=user_email).first()
if token:
service_name = token.service_name
service_config = config[service_name]
client = register_oauth(service_config)
response_json = send_email(service_config,token,client)
if response_json['status_code'] == 200:
return make_response(jsonify(response_json)),200
else:
pass
service_name = get_service_name(user_email)
service_config = config[service_name]
client = register_oauth(service_config)
redirect_uri = url_for('oauth.authorize',_external=True,_scheme='https')
authorization_obj = client.create_authorization_url(redirect_uri=redirect_uri)
authorization_url = authorization_obj['url']
session['user_email'] = user_email
session['service_name'] = service_name
session['redirect_uri'] = redirect_uri
session[f'_{service_name}_authlib_state_'] = authorization_obj['state']
return make_response(jsonify({"authorization_url": authorization_url})),200
class Authorize(MethodView):
def get(self):
user_email = session['user_email']
service_name = session['service_name']
redirect_uri = session['redirect_uri']
service_config = config[service_name]
client = register_oauth(service_config)
token = client.authorize_access_token(redirect_uri=redirect_uri)
authorizer_email = get_authorizer_email_id(service_config,client)
if authorizer_email.lower() != user_email.lower():
response_json = {
'message': f'Authorization attempted from an ID which is not registered with KYC. Please use {user_email} for authorization'
}
return make_response(jsonify(response_json)),401
oauth_token = OAuthToken(
user_email=user_email,service_name=client.name,token_type=token['token_type'],access_token=token['access_token'],refresh_token=token['refresh_token'],expires_at=token['expires_at']
)
db.session.add(oauth_token)
db.session.commit()
response_json = send_email(service_config,oauth_token,client)
return make_response(jsonify(response_json)),200
# define the API resources
auto_email_view = AutoEmail.as_view('auto_email')
authorize_view = Authorize.as_view('authorize')
oauth_blueprint.add_url_rule(
'/oauth/auto_email',view_func=auto_email_view,methods=['GET']
)
oauth_blueprint.add_url_rule(
'/oauth/authorized',view_func=authorize_view,methods=['GET']
)
为了进行测试,后端在127.0.0.1:5000
上运行,而前端在localhost:9000
上运行。将部署该应用程序,以便将服务器和前端托管在同一域的两个子域中。
问题-我收到以下错误:
KeyError: 'user_email'
在
user_email = session['user_email']
似乎会话变量未随回调一起返回,因为Authorize API中的会话变量为空。
我还试图通过传递电子邮件(加密的字符串)作为状态参数来消除会话变量,如下所示:
authorization_obj = client.create_authorization_url(redirect_uri=redirect_uri,state=encrypted_email)
但是,这会导致CSRF错误。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。