无效的 CSRF 令牌,即使它是有效的

Invalid CSRF token even though it is valid

我正在尝试编写一个可以登录 https://shop.footshop.eu/en/profile/login 的脚本 post 请求的负载如下所示: {"login":{"email":"myEmail@gmail.com","password":"myPassword","_csrf_token":"jrqiIKWyueAcSVs2hVCuUhVfSj-sR3eeRSQma1Tz6P0"}}

当我 运行 我的脚本时,我收到响应 200,其中包含以下文本:

{"success":false,"suggestedResponseStatus":400,"message":null,"login":{"title":"form.login.label","type":"object","properties":{"email":{"type":"string","title":"Email","widget":"email","defaultValue":"myEmail@gmail.com","attr":{"required":true,"errors":{"required":"Field is required"}},"disabled":false,"empty":false,"propertyOrder":1},"password":{"type":"string","title":"Password","widget":"password","defaultValue":"","attr":{"required":true,"errors":{"required":"Field is required"}},"disabled":false,"empty":false,"propertyOrder":2},"_csrf_token":{"type":"string","title":"Token","widget":"hidden","defaultValue":"sOM7L-RA6-gm-ZqFjY0RErh69-bjU8n4vGvY_M9ezIk","attr":{"required":false},"disabled":false,"empty":true,"propertyOrder":3}},"defaultValue":{"email":"myEmail@gmail.com","_csrf_token":"sOM7L-RA6-gm-ZqFjY0RErh69-bjU8n4vGvY_M9ezIk"},"errors":["The CSRF token is invalid. Please try to resubmit the form.","Incorrect login"],"action":"\/en\/profile\/login"}}

我不知道我做错了什么

def login(account):
    print("Logging in to account " + account.email)
    session = requests.Session()
    session.headers['accept'] = 'application/json'
    session.headers['content-type'] = 'application/json'
    session.headers['origin'] = 'https://shop.footshop.eu'
    session.headers['referer'] = 'https://shop.footshop.eu/en/profile/login'
    token = None
    while token is None:
        token = get_token(session)
    login_account(account, token, session)


def get_token(session): 
    try:
        headers = {
            "accept": "*/*",
            "origin": "https://shop.footshop.eu",
            "user-agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0"
        }
        resp = session.get(url="https://shop.footshop.eu/en/profile/login", headers=headers)
        soup = bs4.BeautifulSoup(resp.text, "html.parser")
        print(soup.prettify())
        token = json.loads(soup.find('div', {"id": "authentication"}).get('data-json'))['registration']['defaultValue']['_csrf_token']
        return token
    except Exception:
        return None

def login_account(account, token, session):
    print(account.email, account.password, token)
    headers = {
        "accept": "*/*",
        "accept-encoding": "gzip, deflate, br",
        "accept-language": "sk-SK,sk;q=0.9,cs;q=0.8,en-US;q=0.7,en;q=0.6",
        "dnt": "1",
        "origin": "https://shop.footshop.eu",
        "referer": "https://shop.footshop.eu/en/profile/login",
        "user-agent": "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0",
        "sec-ch-ua": '"Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92"',
        "sec-ch-ua-mobile": "?0",
        "sec-fetch-dest": "empty",
        "sec-fetch-mode": "cors",
        "sec-fetch-site": "same-origin"
    }
    form_data = {"login": {"email": account.email,"password": account.password, "_csrf_token": token}}

    resp = session.post(url="https://shop.footshop.eu/en/profile/login", json=form_data, headers=headers)
    print(resp.status_code)
    print(resp.headers)
    print(resp.text)

您可能从 registration 对象中提取了错误的 _csrf_token。我认为正确的是 login object

我注意到,当您使用伪造数据向 https://shop.footshop.eu/en/profile/login 发出 POST 请求时,响应 JSON 包含一个 CSRF 令牌,该令牌与嵌入页面的令牌不同HTML。也许试一试?

import requests

url = "https://shop.footshop.eu/en/profile/login"

headers = {...}

payload = {
    "login": {
        "email": "bogus@bogus.com",
        "password": "bogus",
        "_csrf_token": "bogus"
    }
}

response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()

token = response.json()["login"]["properties"]["_csrf_token"]["defaultValue"]