使用 python 请求时,我收到错误的请求发送到错误的帐户

问题描述 投票:0回答:1

我正在为 Flask 应用程序使用 Python 请求库,该应用程序托管在 Heroku 上。我使用线程实现了一个任务,它将无限期地从其他应用程序获取数据,直到用户自己停止它。理论上,每个用户都有自己的访问令牌和用于 api 调用的刷新令牌,但不知何故,有时 api 请求会发送到错误的帐户。例如,如果用户 A 和 B 都运行该应用程序,则用户 A 收到一封电子邮件,说他们获得了项目 X,但是当用户 A 检查另一个应用程序时,它不会显示项目 X,而是显示用户B 得到了该物品 X。这里可能出了什么问题?我怀疑我使用请求的方式,但我想不出任何原因。令人困惑的部分是它使用正确的用户设置来获取项目,并且仅“尝试”获取满足设置的项目,但项目只是发送到错误的帐户。

def process_search():
    user = request.user
    user.update_user_running_status(True)
    user.set_running_session()

    user.refresh()
    
    # Custom class I made to take the user info, which has token information for the other app
    itemHandler = Handler(user)

    thread = Thread(target=itemHandler.start)
    thread.daemon = True
    thread.start()

    running_status = user.running_status
    current_running_session = user.current_running_session

    return jsonify({'is_running': running_status, "current_running_session": current_running_session}), 200
class Handler:
    allHeaders = {
        "TokenRequest": {
            "x-acme-identity-auth-domain": "api.acme.com",
            "User-Agent": "Acme Device Acme/0.0/iOS/15.2/iPhone",
        },
        "AllRequest": {
            "Accept": "application/json",
            "x-acme-access-token": None,
            "X-Acme-Date": None,
            "Accept-Encoding": "gzip, deflate, br",
            "Accept-Language": "en-US",
            "Content-Type": "application/json",
            "User-Agent": "iOS/16.1 (iPhone Darwin) Model/iPhone Platform/iPhone14,2 AcmeOS/2.112.2",
            "Connection": "keep-alive",
        },
    }

    def __init__(self, user: User) -> None:
        self.user = user
       
        self.requestHeaders = Handler.allHeaders.get("AllRequest")
        self.refreshToken = user.acme_refresh_token
        self.accessToken = user.acme_access_token

        if self.refreshToken == "":
            self.registerAccount()

        self.requestHeaders["x-acme-access-token"] = self.accessToken
        self.requestHeaders["X-Acme-Date"] = self.getDate()

    def registerAccount(self):
        auth_response = self.user.auth_response

        parsed_query = parse_qs(urlparse(auth_response).query)
        reg_access_token = unquote(parsed_query['openid.oa2.access_token'][0])
        device_id = secrets.token_hex(16)
        acme_reg_data = {
            "auth_data": {"access_token": reg_access_token},
            "cookies": {"domain": ".acme.com", "website_cookies": []},
            "device_metadata": {
                "android_id": "52aee8aecab31ee3",
                "device_os_family": "android",
                "device_serial": device_id,
                "device_type": "A1MPSLFC7L5AFK",
                "mac_address": secrets.token_hex(64).upper(),
                "manufacturer": MANUFACTURER,
                "model": DEVICE_NAME,
                "os_version": "30",
                "product": DEVICE_NAME,
            },
            "registration_data": {
                "app_name": APP_NAME,
                "app_version": APP_VERSION,
                "device_model": DEVICE_NAME,
                "device_serial": device_id,
                "device_type": "A1MPSLFC7L5AFK",
                "domain": "Device",
                "os_version": OS_VERSION,
                "software_version": "130050002",
            },
            "requested_extensions": ["device_info", "customer_info"],
            "requested_token_type": [
                "bearer",
                "mac_dms",
                "store_authentication_cookie",
                "website_cookies",
            ],
            "user_context_map": {"frc": self.generate_frc(device_id)},
        }

        reg_headers = {
            "Content-Type": "application/json",
            "Accept-Charset": "utf-8",
            "x-acme-identity-auth-domain": "api.acme.com",
            "Connection": "keep-alive",
            "Accept": "*/*",
            "Accept-Language": "en-US",
        }
        res = requests.post(
            Handler.routes.get("GetAuthToken"),
            json=acme_reg_data,
            headers=reg_headers,
            verify=True,
        )
        if res.status_code != 200:
            print("login failed")
            exit(1)

        res = res.json()
        tokens = res['response']['success']['tokens']['bearer']
        self.accessToken = tokens['access_token']
        self.refreshToken = tokens['refresh_token']
     
        self.user.update_acme_token(self.accessToken, self.refreshToken)

    def start(self):
        while True:
            if not self.user.running_status:
                Offer(self.user).delete_temp_offers()
                break
            # fetch data
          
            response = requests.post(
                self.routes.get("getItems"),
                headers=self.requestHeaders,
                json={
                    "apiVersion": "V2",
                }
            )

我怀疑是requests.Session,所以改成常规请求,但问题还是出现。

python flask python-requests python-multithreading
1个回答
1
投票

这是一个经典的 Python bug,只是以巧妙的方式隐藏起来。

当你这样做时:

        self.requestHeaders = Handler.allHeaders.get("AllRequest")

您没有复制该字典。执行此操作的每个对象都将获得对该同一字典的引用。当您修改字典以设置当前用户的令牌时,您正在修改所有这些。

如果您将其更改为:

        self.requestHeaders = Handler.allHeaders["AllRequest"].copy()

或者,更好的是,只需初始化

__init__
中的字典,那么您的问题就会消失。

© www.soinside.com 2019 - 2024. All rights reserved.