使用 python 个请求获取 CSRF 令牌

Get CSRF token using python requests

我目前正在使用 Python 请求,并且需要一个 CSRF 令牌来登录站点。根据我的理解 requests.Session() 获取 cookie,但显然我需要令牌。而且我还想知道将它放在我的代码中的什么位置。 导入请求

user_name = input('Username:')
payload = {
'username': 'user_name',
'password': 'randompass123'
}


with requests.Session() as s:
p = s.post('https://examplenotarealpage.com', data=payload)

参见下面的代码示例。您可以直接使用它来登录只使用cookies来存储登录信息的网站。

import requests

LOGIN_URL = 'https://examplenotarealpage.com'
headers = {
    'accept': 'text/html,application/xhtml+xml,application/xml',
    'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}

response = requests.get(LOGIN_URL, headers=headers, verify=False)

headers['cookie'] = '; '.join([x.name + '=' + x.value for x in response.cookies])
headers['content-type'] = 'application/x-www-form-urlencoded'
payload = {
    'username': 'user_name',
    'password': 'randompass123'
}

response = requests.post(LOGIN_URL, data=payload, headers=headers, verify=False)
headers['cookie'] = '; '.join([x.name + '=' + x.value for x in response.cookies])

CSRF 令牌有几个可能的位置。不同的网站使用不同的方式将其传递给浏览器。以下是其中一些:

  • 它可以带有响应 headers,在这种情况下获取它很容易。
  • 有时页面元包含 CSRF 令牌。您必须解析页面的 html 内容才能获取它。为它找到合适的 CSS 选择器。看一个例子:

    from bs4 import BeautifulSoup
    soup = BeautifulSoup(response.text, 'lxml')
    csrf_token = soup.select_one('meta[name="csrf-token"]')['content']
    
  • 它可以在带有 JavaScript 代码的脚本标签内。得到它会很棘手。但是,您始终可以使用 regex 来隔离它。

import requests
from bs4 import BeautifulSoup
headers = {'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 
           (KHTML, like Gecko) Chromium/80.0.3987.160 Chrome/80.0.3987.163 
           Safari/537.36'
 }
login_data = {
             'name' : 'USERNAME',
             'pass' : 'PASSWORD',
             'form_id':'new_login_form',
             'op':'login'
  }

with requests.Session() as s:
    url = 'https://www.codechef.com/'
    r = s.get(url,headers=headers,verify=False)
    #print(r.content) # to find name of csrftoken and form_build_id
    soup = BeautifulSoup(r.text, 'lxml')

    csrfToken = soup.find('input',attrs = {'name':'csrfToken'})['value']
    form_build_id = soup.find('input',attrs = {'name':'form_build_id'}) 
    ['value']

    login_data['csrfToken'] = csrfToken
    login_data['form_build_id'] = form_build_id

    r = s.post(url,data=login_data,headers = headers)
    print(r.content)

您可以直接使用它,但需要更改的地方很少:
1.check 浏览器网络选项中的用户代理
2.check 你的 csrf-token 名称属性和 form_build_id 通过打印(r.content) 并找到 csrftoken 和 form-b​​uild-id 并检查它们的名称属性。

最后一步:

在您的 r.content 中搜索注销,如果是他们的,那么您正在登录。

我把它放在这里是因为我花了很多时间和网络交互分析才找到这个答案...

我必须使用 python/requests 登录 swagger/openAPI。我可以使用浏览器登录该站点,但要使用请求登录,我需要 x_csrf_token/sails.sid 组合...

在这里和其他地方尝试所有答案并失败后,检查了浏览器通信。事实证明,唯一的方法是首先获取 'sails.sid',然后对未记录的(?)/csrfToken 执行 GET...

base_host = '...'
base_path= '/api/v2'
base_url = base_host + base_path
data = {
  "email": "...",
  "password": "..."
}
resp = requests.post(f"{base_url}/login", data=data)
session_cookie = resp.cookies
session_dict=session_cookie.get_dict()

sails_sid = session_dict.get('sails.sid','could not get valid [sails.sid]')
print(f'sails.sid:{[sails_sid]}')

然后:

cookies = {
    'sails.sid': sails_sid,
}
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:100.0) Gecko/20100101 Firefox/100.0',
}
r2 = requests.get(f"{base_url}/csrfToken",  cookies=cookies, headers=headers)
print(r2.json())

请注意,在我的情况下它是 emai/password...我通过 Firefox 检查分析浏览器发现了所有这些,因此这也可能是您最后的选择...