【问题标题】:Python request sessions is not working for put/post in next callPython 请求会话不适用于下一次调用中的 put/post
【发布时间】:2018-07-24 06:53:08
【问题描述】:

您好,我正在尝试访问一个 rest api,只有在登录后才能访问。我正在使用下面的代码,但得到 401,访问被拒绝。我确信如果相同的 cookie 将应用于下一次 put 调用,它不会拒绝访问。但是python会话没有使用相同的cookie..而是添加新的cookie..谢谢..

with requests.Session() as s:
    logging.info("Trying to login")
    response1 = s.post("https://localhost:8080/api/authentication?j_username=admin&j_password=admin", verify=False)

    for cookie in s.cookies:
        logging.info(str(cookie.name) + " : " + str(cookie.value))
    logging.info("logged in successfully " + str(response1.status_code))
    url = url1 % (params['key'])
    logging.info("inspector profile inpect api : " + url)
    response = s.put(url, verify=False)
    for cookie in s.cookies:
        logging.info(str(cookie.name) + " :: " + str(cookie.value))
    logging.info("code:-->"+ str(response.status_code))

输出是

CSRF-TOKEN : c3ea875b-3df9-4bd4-992e-2b976c150ea6 
JSESSIONID : M3WWdp0PO95ENQSJciqiEbiHZR6ge7O8HkKDkY6R 
logged in successfully 200 
profile api : localhost:8080/api/test/283 
CSRF-TOKEN :--> e5b64a66-5402-430b-8f51-d8d7549fd84e 
JSESSIONID :--> JUZBHKmqsitvlrPvWuaqfTJNH1PIJcEXPTkPYPKk 
CSRF-TOKEN :--> c3ea875b-3df9-4bd4-992e-2b976c150ea6 
JSESSIONID :--> M3WWdp0PO95ENQSJciqiEbiHZR6ge7O8HkKDkY6R
code:401

看起来下一个 api 调用没有使用 cookie,请帮帮我。

【问题讨论】:

  • 您使用的是哪个版本的requests?早期版本没有 cookie 持久性,所以您是否尝试过手动为它们提供 PUT,即s.put(url, cookies=s.cookies, verify=False)?最后,你怎么能确定 Python 发送了错误的 cookie 而不是后端重建 CSRF-TOKENJSESSIONID - Python 本身不会生成这些值,所以它们肯定来自后端。

标签: python python-2.7 python-requests


【解决方案1】:

刚刚调试完同样的问题。

根据 RFC 2965:

术语有效主机名与主机名有关。 如果是主机名 不包含点,有效的主机名是带有 string .local 附加到它。 否则有效的主机名是 与主机名相同。请注意,所有有效的主机名 至少包含一个点。

Python Requests 模块使用 http.cookiejar 模块来处理 cookie。它会在将接收到的 cookie 应用于会话之前对其进行验证。

使用以下代码获取调试输出:

import logging
import http.cookiejar

logging.basicConfig(level=logging.DEBUG)
http.cookiejar.debug = True

这是一个示例,当接收到的 cookie 未应用时:

DEBUG:http.cookiejar:add_cookie_header
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost
DEBUG:urllib3.connectionpool:http://localhost:80 "POST /api/login HTTP/1.1" 200 6157
DEBUG:http.cookiejar:extract_cookies: Date: Thu, 30 Apr 2020 15:45:11 GMT
Server: Werkzeug/0.14.1 Python/3.5.3
Content-Type: application/json
Content-Length: 6157
Set-Cookie: token=1234; Domain=localhost; Path=/
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
DEBUG:http.cookiejar: - checking cookie token=1234
DEBUG:http.cookiejar:   non-local domain .localhost contains no embedded dot

发送到localhost的请求,期望网络服务器将cookie的域部分设置为localhost.local

这是一个示例,当接收到的 cookie 被正确应用时:

DEBUG:http.cookiejar:add_cookie_header
DEBUG:urllib3.connectionpool:Starting new HTTP connection (1): localhost
DEBUG:urllib3.connectionpool:http://localhost:80 "POST /api/login HTTP/1.1" 200 6157
DEBUG:http.cookiejar:extract_cookies: Date: Thu, 30 Apr 2020 15:52:08 GMT
Server: Werkzeug/0.14.1 Python/3.5.3
Content-Type: application/json
Content-Length: 6157
Set-Cookie: token=1234; Domain=localhost.local; Path=/
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
DEBUG:http.cookiejar: - checking cookie token=1234
DEBUG:http.cookiejar: setting cookie: <Cookie token=1234 for .localhost.local/>

如果您无法修复 Web 服务器,请在您的请求中使用 127.0.0.1 而不是 localhost

response1 = s.post("https://127.0.0.1:8080/api/authentication?j_username=admin&j_password=admin", verify=False)

【讨论】:

    【解决方案2】:

    这段代码对我有用:

    from requests import Session
    s = Session()
    s.auth = ('username', 'password')
    s.get('http://host'+'/login/page/')
    response = s.get('http://host'+'/login-required-pages/')
    

    【讨论】:

    • 我也可以在登录后调用get请求...但不是put方法
    • @SunnyGupta 您的后端的输出是什么?如果合适,请将您的代码推送到 github 并共享 repo。
    【解决方案3】:

    尽管有 CSRF-TOKENJSESSIONID cookie,但您实际上并未成功通过该网站的身份验证。会话数据(包括您是否通过身份验证)存储在服务器端,而您获取的那些 cookie 只是此类会话数据的密钥。

    我看到您的身份验证方式的一个问题是您将用户名和密码作为查询字符串发布,这通常仅用于 GET 请求。

    尝试使用适当的有效负载进行发布:

    response1 = s.post("https://localhost:8080/api/authentication", data={'j_username': 'admin', 'j_password': 'admin'}, verify=False)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-06-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-27
      • 2019-04-11
      • 1970-01-01
      相关资源
      最近更新 更多