我正在用Python开发一个报告工具,它将从ServiceNow的jsonweb服务获取数据。我们的ServiceNow实例使用普通的用户id/pw认证和SHA-1认证。我的问题是我不能用我的脚本访问jsonweb服务结果页(https://servicenowserver.com/table.do?JSONv2&sysparm_query=active=true^number=12345678)从那里获取数据。我可以用我的脚本登录到主页(https://servicenowserver.com),它进行身份验证并给出http200,但是当我调用JSON webservice页面时,它给了我http401(未经授权)。在
一旦我通过浏览器登录到ServiceNow,并且我的会话开始,我就可以在一个新的选项卡上调用JSON服务,它会显示结果,但这与我的Python脚本不起作用。我试图同时使用urllib3
和requests
库和一个会话参数来保持会话的打开,但它也不起作用。我想我的脚本只是在调用主页后立即关闭会话。我也试着不走运地传递饼干。在
长话短说:它可以从我的浏览器工作,但如果我使用Python脚本就不行了。在
你知道我应该如何认证才能得到JSON结果吗?或者至少如果有人能指导我如何得到更详细的调试?在
下面您可以找到我尝试过的解决方案之一:
import requests
s = requests.session()
s.auth = ('user', 'password')
s.verify = 'sn.cer'
r = s.get('https://servicenowserver.com', verify=True)
print (r) # This gives HTTP 200
r2 = s.get ('https://servicenowserver.com/table.do?JSONv2&sysparm_query=active=true^number=12345678', verify=True, cookies=s.cookies)
print (r2) # This gives HTTP 401
我可以想出解决办法,所以我在这里发表。我要在这里发布的并不是我问题的确切解决方案,而是了解和检查如何跟踪身份验证的一般方法。在我的案例中,我使用这种技术来跟踪登录过程。在
在我的例子中,servicenew使用基于cookie的身份验证,并在4个页面之间来回传递信息。第一个页面生成一个名为NSC的ID,并将其作为cookie传递给第二个页面,以生成另一个名为SMSESSION ID的ID,然后将其与cookie中的NSC ID一起传递到第三个页面,以生成最终的JSESSION ID。最后,该进程将所有先前生成的3个ID传递到cookie中的登录页面,以验证会话。在
我用Google开发工具来解决这个问题。我建议你做以下事情。在
1.)在googlechrome中转到你想通过的登录页面,等待站点加载。暂时不要登录。在
2.)打开开发人员工具(右键单击,检查元素菜单选项)。如果您熟悉其他浏览器的开发功能,那也可以。在
3.)转到“开发工具”的“应用程序”选项卡,然后单击左侧菜单栏上的“清除存储”。这将清除为此页存储的所有数据。你可以通过清除cookies和其他数据在Chrome的设置菜单中做同样的事情。这需要清除页面上已经发生的所有历史步骤,以免造成任何混乱。在
4.)完成后,转到Dev Tools的Network选项卡,然后单击Clear menu选项(记录按钮旁边)。这将清除网络日志历史记录。在
5.)下一步,勾选“网络”选项卡上的“保留日志”复选框。这将允许我们跟踪每个步骤,即使在任何重定向的情况下。如果不勾选此选项,一旦登录页面将您重定向到其他位置,您将丢失所有数据,因为它会清除网络日志。在
6.)现在我们删除了所有的历史数据并建立了一切,我们可以开始调查了。使用您的用户id和密码登录该页面,并保持开发人员工具处于打开状态,这样您就可以查看所有网络请求。等待登录过程完成,然后开始逐个检查网络日志条目。在
7.)您将看到一些GET和POST请求。这是您的登录流程。双击第一个打开它。它将显示按部分组织的信息(常规、响应头、请求头、查询参数、表单数据等)。这是web服务器和客户机(您的机器)之间发生的信息交换。你需要和你一起模拟脚本。这个意味着无论您在请求头部分看到什么,您都需要在脚本中传递完全相同的内容。通过这种方式,您将收到完全相同的响应头,并且您可以从中获取前进所需的所有信息。在
让我给你举个例子。在
在我的第一个POST请求中,我可以在网络日志中看到以下内容:
无论您在请求头部分中看到什么,都需要将其传递到第一个URL以获取响应头信息。如果您在响应头中看到,我收到了服务器提供的几个id。这意味着我需要用Python编写我的第一个请求,以便传递与请求头中相同的信息。像这样:
^{pr2}$就这样。如果你有更多的重定向,你需要遵循同样的过程,直到你通过最后一页和你的会话认证。在此之后,您可以使用收集的cookie信息来验证所有即将到来的请求。如您所见,我使用
s = requests.session()
命令启动了一个会话,我可以使用该会话提交所有请求,而无需为所有请求传递用户id和pw。当你需要发送GET和se时要小心发送邮件请求。您可以在标题的“常规信息”部分看到这一点。在还有一个重要的提示。如果站点上有重定向,请在
requests
中使用allow_redirects=False
。通过这种方式,您可以确保您的请求不会被重定向到其他站点,并且您可以获得正确的响应头信息。在相关问题 更多 >
编程相关推荐