在具有 CSRF 保护的 Rails 应用上向 Ruby 发出 POST 请求时出现 404 错误

404 error when making POST request to Ruby on Rails app with CSRF protection

所以有 this 将引文字符串解析为 BibTex 格式的开源应用程序,我正在尝试使用 Python 请求将其功能集成到我的项目中。

我知道该表单具有 CSRF 保护,因此我确保将令牌作为 POST 请求的一部分包含在内,但这并不成功,returning a 404 错误:

from requests import Session
from lxml import html

citations = ["107 F. Scarpa, S. Blain, T. Lew, D. Perrott, M. Ruzzene and J. Yates, Elastic buckling of hexagonal chiral cell honeycombs, Composites, Part A, 2007, 38(2), 280–289"]
s = Session()
url = 'https://anystyle.io/'
page = s.get(url)
tree = html.fromstring(page.content)
csrf_token = tree.xpath("/html/head/meta[4]/@content")[0]
response = s.post(
    headers = {
        'Origin': url,
        'Referer': url,
        'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0',
        'Accept': 'application/json, text/plain, */*',
        'Accept-Language': 'en-US,en;q=0.5',
        'Content-Type': 'application/json;charset=utf-8',
        'Connection': 'keep-alive',
        'X-CSRF-TOKEN': csrf_token
    },
    url = url,
    params = (
        ('format', 'json'),
    ),
    json = {
        'input': citations
    },
    cookies = {
        '_any_style_session': s.cookies.get('_any_style_session')
    }
)
response.json() 

我想知道的是,上述代码是否正确解决了 CSRF 问题以 return 成功请求,或者 app 是否以这种方式设计以防止自动请求。

/parse添加到POST URL:

from requests import Session
from lxml import html

citations = ["107 F. Scarpa, S. Blain, T. Lew, D. Perrott, M. Ruzzene and J. Yates, Elastic buckling of hexagonal chiral cell honeycombs, Composites, Part A, 2007, 38(2), 280–289"]
s = Session()
url = 'https://anystyle.io'
page = s.get(url)
tree = html.fromstring(page.content)
csrf_token = tree.xpath("/html/head/meta[4]/@content")[0]
response = s.post(
    headers = {
        'X-CSRF-TOKEN': csrf_token  # <-- only this header is needed
    },
    url = url + '/parse',           # <-- add '/parse' here!
    params = (
        ('format', 'json'),
    ),
    json = {
        'input': citations
    },
    # cookies= are not needed:
)
print( response.json() )

打印:

[[['citation-number', '107'], ['author', 'F.'], ['author', 'Scarpa,'], ['author', 'S.'], ['author', 'Blain,'], ['author', 'T.'], ['author', 'Lew,'], ['author', 'D.'], ['author', 'Perrott,'], ['author', 'M.'], ['author', 'Ruzzene'], ['author', 'and'], ['author', 'J.'], ['author', 'Yates,'], ['title', 'Elastic'], ['title', 'buckling'], ['title', 'of'], ['title', 'hexagonal'], ['title', 'chiral'], ['title', 'cell'], ['title', 'honeycombs,'], ['journal', 'Composites,'], ['journal', 'Part'], ['journal', 'A,'], ['date', '2007,'], ['volume', '38(2),'], ['pages', '280–289']]]