基于[CURL的优慕课教务系统模拟登陆]

登陆需要用到三个接口:

获取第一次的Cookie:
http://jwc.sdfmu.edu.cn/academic/common/security/login.jsp

利用获取的Cookie获得验证码:
http://jwc.sdfmu.edu.cn/academic/getCaptcha.do

利用验证码和Cookie进行Post登陆:
http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check

将利用到以下知识:

1、Curl不利用CookieJar进行Cookie的存储
2、Curl获取302跳转到的目标页面
3、Curl进行post登陆

第一步:利用Curl获取Cookie,不使用CookieJar

由于是后端对接,所以使用了php进行获取Cookie,不使用CookieJar:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
private function getcookie(){
$session = curl_init();
$url = 'http://jwc.sdfmu.edu.cn/academic/common/security/login.jsp';
curl_setopt($session, CURLOPT_URL,$url);
curl_setopt($session, CURLOPT_HEADER, 1); //保留头信息获取cookie
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($session);
curl_close($session);
list($header, $body) = explode("\r\n\r\n", $content);
preg_match("/set\-cookie:([^\r\n]*)/i", $header, $matches);
$temp = $matches[1];
preg_match_all('/JSESSIONID=[A-Za-z0-9=.]+/i', $temp, $cookie);//正则匹配JSESSIONID后的内容
return $cookie[0][0];
}

第二步:利用Cookie得到验证码

由于验证码是图片性质,所以处理起来我用了笨办法,将curl得到的图片进行转存,转存到本地然后返回给前端一个jpg文件名和第一步得到的cookie,因为没有利用session所以只能把cookie给前端,登录的时候再通过ajax返回给我;为了避免图像的重复,利用MD5作为文件名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public function getimg(){
$cookie = $this -> getcookie();
$session = curl_init();
$url = 'http://jwc.sdfmu.edu.cn/academic/getCaptcha.do';
curl_setopt($session, CURLOPT_URL,$url);
curl_setopt($session, CURLOPT_HEADER, 0); //头信息剔除
curl_setopt($session, CURLOPT_COOKIE,$cookie);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$content = curl_exec($session);
curl_close($session);
$tmpFile = tempnam(sys_get_temp_dir(), 'image');//创建一个缓存文件,用于保存验证码
$resource = fopen($tmpFile, 'w');//打开缓存文件
fwrite($resource,$content);//写入图片
fclose($resource);//关闭
$md5FileName = md5_file($tmpFile);//生成文件MD5,消除歧义
$returnFile = './image/' . $md5FileName . '.jpg';//构造最终返回给前端的文件名
copy($tmpFile, $returnFile);//拷贝到最终文件
@unlink($tmpFile);//删除临时文件
$returnFile = $md5FileName.'.jpg';
$rawData = array('Cookie'=>$cookie,'img'=>$returnFile);//将Cookie以及img信息返回给前端进行加载和二次接力
$response = $this -> encodeJson($rawData);
echo $response;
}


第三步:利用Cookie进行post登陆

通过观察请求包发现:

1
2
3
4
5

发送的post请求是一个raw格式并且有```urlencode()```转码

因此我们先构造一个post包:
>```$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;

第二步发现还必须往header中加入content-type:application/x-www-form-urlencoded,否则post raw格式服务端会拒绝,提示验证码错误

因此就得到了前两步的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public function login($user,$pass,$code,$cookie,$img){
$file = './image/'.$img;//得到当时回传的文件名
if (file_exists($file)){
unlink($file);//删除刚才创建的验证码,其实也可以用计划任务删
}
$url = "http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check";//post url
$ch = curl_init();
$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;//RAW格式post包
$headers = array(
"content-type:application/x-www-form-urlencoded"
);//构造header
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);//启用post
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);//post data
curl_setopt($ch, CURLOPT_COOKIE, $cookie);//携带cookie post
}

执行到上面的第三步我们发现一个问题,这个是否登录成功会反馈给一个http 302状态码,然而curl好像没办法获得302跳转到的界面,因此就没法判断html内容是否成功了,经过查阅资料发现:curl_getinfo()可以获得HTTP头,也就是可以解析302里面的内容

当我把302解析之后发现返回了一个数组,key下面的’redirect_url’内对应着跳转到的页面如果是http://jwc.sdfmu.edu.cn/academic/index_new.jsp则成功登录,如果是另外一个则登录失败,因此得到了最终版的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public function login($user,$pass,$code,$cookie,$img){
$file = './image/'.$img;
if (file_exists($file)){
unlink($file);
}
$url = "http://jwc.sdfmu.edu.cn/academic/j_acegi_security_check";
$ch = curl_init();
$post_data = "j_username=".$user."&j_password=".$pass."&j_captcha=".$code;
$headers = array(
"content-type:application/x-www-form-urlencoded"
);
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_HTTPHEADER,$headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
$content = curl_exec($ch);
$header = curl_getinfo($ch);
if ($header['redirect_url']=="http://jwc.sdfmu.edu.cn/academic/index_new.jsp"){
echo 'true';
curl_close($ch);

} else {
echo 'false';
curl_close($ch);
}

}

前端根据True or False判断是否登录成功,这样就大功告成了!


小结

通过这次的综合训练,学会掌握了Curl的进阶用法,以及正则表达式的用法,虽然用的不熟练但是也是实战了,还学会了利用curl获取302里面的跳转信息判断是否登录正常,这次弄得我快吐了,再也不想写代码了,好好学习了,还是学习简单,心无旁骛了!太费劲了吧!!!

  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信