首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >eBay和Authlib非传统令牌类型

eBay和Authlib非传统令牌类型
EN

Stack Overflow用户
提问于 2020-04-01 03:14:30
回答 1查看 208关注 0票数 0

我正在尝试使用Authlib库访问new eBay REST API (作为授权码授权)

这是我的代码;

代码语言:javascript
复制
import json
import os
import webbrowser
from time import time

from authlib.integrations.requests_client import OAuth2Session
from rpi_order_data_sync import settings


def auth(seller):
    def token_updater(token, seller=seller):
        if not os.path.exists(seller):
            open(seller, "w").close()
        with open(seller, "w") as token_file:
            json.dump(token, token_file)

    scope = ["https://api.ebay.com/oauth/api_scope/sell.fulfillment.readonly"]

    if not os.path.exists(seller):

        ebay = OAuth2Session(
            settings.E_APP_ID,
            settings.E_CERT_ID,
            redirect_uri=settings.E_RU_NAME,
            scope=scope,
        )

        uri, state = ebay.create_authorization_url(
            "https://auth.sandbox.ebay.com/oauth2/authorize",
        )

        print("Please go to {} and authorize access.".format(uri))

        try:
            webbrowser.open_new_tab(uri)
        except webbrowser.Error:
            pass

        authorization_response = input("Please enter callback URL: ")  # nosec

        token = ebay.fetch_token(
            "https://api.sandbox.ebay.com/identity/v1/oauth2/token",
            authorization_response=authorization_response,
        )

        print(token)

        token_updater(token)

        return ebay

问题是eBay的令牌响应有一个非常规的令牌类型,名为“用户访问令牌”,而不是“持有者”。因此我得到了这个错误;

代码语言:javascript
复制
Traceback (most recent call last):
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 37, in __call__
    req.url, req.headers, req.body = self.prepare(
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/oauth2/auth.py", line 91, in prepare
    sign = self.SIGN_METHODS[token_type.lower()]
KeyError: 'user access token'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/bin/rods", line 11, in <module>
    load_entry_point('rpi-order-data-sync', 'console_scripts', 'rods')()
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 829, in __call__
    return self.main(*args, **kwargs)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 782, in main
    rv = self.invoke(ctx)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 1259, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 1066, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/click/core.py", line 610, in invoke
    return callback(*args, **kwargs)
  File "/home/thiras/HDD/freelancer/contentassasin/rpi-order-data-sync/rpi_order_data_sync/main.py", line 132, in sync_ebay_orders
    orders = ebay.get(
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 543, in get
    return self.request('GET', url, **kwargs)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 113, in request
    return super(OAuth2Session, self).request(
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 516, in request
    prep = self.prepare_request(req)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/sessions.py", line 449, in prepare_request
    p.prepare(
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/models.py", line 318, in prepare
    self.prepare_auth(auth, url)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/requests/models.py", line 549, in prepare_auth
    r = auth(self)
  File "/home/thiras/.local/share/virtualenvs/rpi-order-data-sync-tA0i1rrc/lib/python3.8/site-packages/authlib/integrations/requests_client/oauth2_session.py", line 41, in __call__
    raise UnsupportedTokenTypeError(description=description)
authlib.integrations.base_client.errors.UnsupportedTokenTypeError: unsupported_token_type: Unsupported token_type: 'user access token'

我注意到Authlib文档中的Compliance fix for non-standard部分,但我不知道如何修复,甚至不能以这种方式进行修复。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-04-03 06:00:33

我找到了一个解决方案,它也适用于requests-oauthlib包。到目前为止,它似乎工作得无懈可击。主要的问题是创建一个假的request.Response模型,因为request.Response没有.text.content属性的设置器,所以修改它们是不可能的。

因此,我创建了一个只模拟.json()方法的FakeResponse类,因为它是Authlib唯一使用的方法。

代码语言:javascript
复制
class FakeResponse:
    """ Fake Class for Request Response class. """

    def __init__(self, data):
        self.data = data

    def json(self):
        """ Mocks requests.Response.json(). """
        return self.data

之后,我创建了一个access_token_response钩子;

代码语言:javascript
复制
def non_compliant_token_type(resp):
    data = resp.json()
    data["token_type"] = "Bearer"
    fake_resp = FakeResponse(data=data)
    return fake_resp

如果你有更好的答案或任何改进建议,请让我知道。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60958170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档