Python 获取 JSESSIONID

最近要帮朋友做一个刷单的工具,有货了自动抢;登录后的管理平台只支持IE,技术比较落后,应该是近几年没有大的升级,页面是jsp的,里边的js乱七八糟,其中还有jsp请求动态输出js的,页面也是各种iframe嵌套;

刚开始就遇到了第一个问题,登录后要记住JSESSIONID的问题;

问题描述

登录页面是 post 表单提交,提交后服务器验证,如果通过,302 跳个人中心页面,然后就可以查询个人信息、订单之类的数据;

想用 python 模拟这个登录过程,并调用登录后的查询接口,但是普通的模拟请求,能够登录成功,但取不到 cookie 中的 JSESSIONID;

req = request.Request(login_url, data=byte_data, headers=headers)
print(req.headers.get('Set-Cookie', None)) # None,没有 Set-Cookie
page = request.urlopen(req).read()
html = page.decode('gb2312')

因为不是在浏览器环境中,所以没法采用先登录,后取cookie的策略;

问题分析

JSESSIONID 是 tomcat 服务器下的 sessionid,用于验证访客身份,第一次访问页面时,服务器就给该访客分配一个 sessionid,通过响应头中的 Set-Cookie 首部告知浏览器,然后浏览器就把这个 sessionid 存到 cookie 中,之后的每次请求中,cookie 中都会带着这个 sessionid;

* JSESSIONID 只会在动态响应的页面/请求中返回,像 .html、.js、.css 这种静态资源,只要没有走后台的 java 代码,仅仅是服务器找到资源返回的话,是不会带 Set-Cookie 首部的,也就不会返回 JSESSIONID

登录之后,服务器会在该 sessionid 对应的信息中更改登录状态,下次请求,根据 sessionid 来校验登录;

也可以用这个来做单点登录限制,如果用户已经通过某一个 sessionid 登录,换个浏览器再次登录时,sessionid 会变,服务器需要将之前的 sessionid 对应的登录状态改为未登录,这样,之前的网页再刷新,就取不到用户信息了;

如果 sessionid 泄露,拿到该信息后,到浏览器中修改 sessionid,就直接越过了登录,获得和真实用户一样的操作权限了;如果服务器仅仅是用 sessionid 做单点登录的判断,两方就会同时在线,突破了单点登录的限制;

模拟登录请求的过程中,因为是首次请求(请求头中没有带 sessionid 的 cookie),所以服务器会分配一个 sessionid,但是 Set-Cookie 首部是在 302 那个响应头中返回的,python 的请求模块接收到 302,就按照响应头中的 Location 首部跳转到下一个页面了,下一个页面继续返回,覆盖了之前的 302 响应信息;

下一个响应(页面)状态码为 200,但该响应的头部中,并没有 Set-Cookie 首部,所以就获取不到 JSESSIONID 了;

解决方案

解决方案有两种,第一种是直接从登录接口获取,第二种是从其他地方获取,然后拿过来绑定登录操作;

解决方案1

上面分析中提到,302 跳转的下一个响应覆盖了 302 本身的响应,那直接禁止 302 跳转就可以解决问题了,即服务器返回 302,但 python 请求模块不做处理,不继续发出请求;

allow_redirects,这个字段就是控制服务器返回 302 之后,要不要重定向;默认 True-重定向;

# 获取 sessionid
s = requests.session()
resp = s.post(login_url, data=byte_data, headers=gl_headers, allow_redirects=False)

cookie1 = resp.headers.get('Set-Cookie', '') 
js_id = cookie1.split(';')[0]
js_id = js_id.split('=')[-1]

if js_id == '':
    print(r'未获取到JSESSIONID')
    return False
print(js_id)

用此方案,还需要取响应的状态码或头部的 Location 首部来判断是否登录成功;

解决方案2

从网站中找一个走了后台代码但不需要登录的页面/接口(状态码非 302),在程序中正常请求这个页面/接口,就能获取到 JSESSIONID 了;

req = request.Request(test_url, headers=headers)
resp = request.urlopen(req)
cookie1 = resp.headers.get('Set-Cookie', '') 

如何找到这个页面/接口?

可以打开 Chrome 的开发者工具,找到 cookie,清空,然后刷新页面,看 cookie 是否新增进来了;如果是,就说明当前页面有动态页面/接口,切换到 Network,在里面找包含 Set-Cookie 首部的响应,用此 url 就能获取到 JSESSIONID 了;

或者直接找以 .jsp 结尾的页面/请求,用对应的 url 就能获取到;

如果这篇文章对你有用,可以点击下面的按钮告诉我

3

发表回复