如何在授权代码授予流程OAuth 2中将数据从主要API传递到重定向的API?

问题描述

我正在使用Authlib的Flask OAuth客户端编写用于授权代码授予范例的OAuth客户端应用程序。该应用程序分为两个API

  1. AutoEmail-从前端React应用程序调用,如果访问令牌可用于数据库中的用户,则代表用户发送电子邮件,或触发Gmail授权URL。
  2. 授权-从授权服务器回叫的重定向URL的端点。触发后,请求访问令牌,插入到DB,然后发送电子邮件

要使第二个API起作用,它需要从前端收到的用户电子邮件。我需要电子邮件

  1. 弄清楚服务名称-google / outlook,以便我可以用它来创建客户端

client = oauth.create_client(service_name)

  1. 运行验证。

这是代码

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错误

我该如何解决并将电子邮件传递到回调(授权)API中?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...