分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 技术分享

使用OkHttp模拟登陆LeetCode

发布时间:2023-09-06 02:04责任编辑:苏小强关键词:暂无标签

前言

网上有很多模拟登陆 LeetCode 的教程,但是基本都是使用 Python 来实现的。作为一个 Java 语言爱好者,因此想用 Java 来实现下。在实现的过程中,也遇到了一些坑点,故在此作为记录。

过程

根据浏览器F12分析登陆页面

从上图可以看出,LeetCode 生成一个 token ,然后在登陆的时候带上这个信息,因此我们模拟登陆的大致思路:首先获取得到 cookie(包含有token),然后在登陆的时候带上这个 cookie 信息,完成 LeetCode 的验证机制,进行模拟登陆。
但是直接进行模拟带上 login(用户名)、password(密码)、csrfmiddlewaretoken(验证信息)是失败的,提示 Forbidden。思考无果,另开思路。
用 fiddler 进行抓包,未登陆状态,数据如下图(也可用浏览器F12来进行分析):

登陆状态,数据如下图,从图中,我们可以发现,其 Content-Type 字段与我们之前常见的值不一样,其是 multipart/form-data 格式,因此我们在模拟登陆,要将其考虑进来。

创建一个 multipart/form-data 的媒体格式,然后生成我们要的请求体,至于我们要的是哪种请求体,其格式可以从 fiddler 抓包的结果获悉。
在SyntaxView中具体的详情如下:

值得注意的是 Content-Type 中的boundary只有四个“-”,而在请求体中有六个“-”,之前因为忽略了这个,一直被拒绝访问(挺坑爹的

public static final String boundary = "----WebKitFormBoundaryhG2vKxp7y2GAwhPX";public static final MediaType MULTIPART = MediaType.parse("multipart/form-data; boundary=" + boundary);String form_data = "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"login\"" + "\r\n\r\n" ???????????????+ usrname + "\r\n" ???????????????+ "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"password\"" + "\r\n\r\n" ???????????????+ passwd ???????????????+ "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\"" + "\r\n\r\n" ???????????????+ csrftoken + "\r\n" ???????????????+ "--" + boundary + "--"; ???????RequestBody requestBody = RequestBody.create(MULTIPART,form_data);

结果

将其返回的报文打印出来,得到如下信息则表示模拟登陆成功

从 fiddler 的抓包结果中也可以证实这点

代码

package LeetCodeLogin;import okhttp3.*;import org.jsoup.Connection;import org.jsoup.Jsoup;import java.io.IOException;import java.util.*;import static java.lang.System.out;public class Login { ???public static final String boundary = "----WebKitFormBoundaryhG2vKxp7y2GAwhPX"; ???public static final MediaType MULTIPART = MediaType.parse("multipart/form-data; boundary=" + boundary); ???public static void main(String... args) throws IOException { ???????Scanner scanner = new Scanner(System.in); ???????String url = "https://leetcode.com/accounts/login/"; ???????String usrname = "xxx"; ???????String passwd = "xxx"; ???????Connection.Response response1 = Jsoup.connect(url) ???????????????.method(Connection.Method.GET) ???????????????.execute(); ???????String csrftoken = response1.cookie("csrftoken"); ???????String __cfduid = response1.cookie("__cfduid"); ???????out.println("csrftoken = " + csrftoken); ???????out.println("__cfduid = " + __cfduid ); ???????OkHttpClient client = new OkHttpClient().newBuilder() ???????????????.followRedirects(false) ???????????????.followSslRedirects(false) ???????????????.build(); ???????String form_data = "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"login\"" + "\r\n\r\n" ???????????????+ usrname + "\r\n" ???????????????+ "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"password\"" + "\r\n\r\n" ???????????????+ passwd ???????????????+ "--" + boundary + "\r\n" ???????????????+ "Content-Disposition: form-data; name=\"csrfmiddlewaretoken\"" + "\r\n\r\n" ???????????????+ csrftoken + "\r\n" ???????????????+ "--" + boundary + "--"; ???????RequestBody requestBody = RequestBody.create(MULTIPART,form_data); ???????Request request = new Request.Builder() ???????????????.addHeader("Content-Type", "multipart/form-data; boundary=" + boundary) ???????????????.addHeader("Connection","keep-alive") ???????????????.addHeader("Accept","*/*") ???????????????.addHeader("Origin","https://leetcode.com") ???????????????.addHeader("Referer",url) ???????????????.addHeader("Cookie","__cfduid=" + __cfduid + ";" + "csrftoken=" + csrftoken) ???????????????.post(requestBody) ???????????????.url(url) ???????????????.build(); ???????Response response = client.newCall(request).execute(); ???????out.println(response.message()); ???????out.println(response.headers()); ???????out.println(response.body().string()); ???}}

需要注意的是,在上述代码中,我们通过下述代码禁止了重定向,来自己处理重定向请求,可参考使用OkHttp进行重定向拦截处理,若是没有进行重定向拦截,也会使得模拟登陆失败。

 ???.followRedirects(false) ???.followSslRedirects(false)

写在最后

本次模拟登陆,虽然代码很简单,但是确实也经历了一些波折,比对过 Python 和 Js 写的模拟登陆的代码,用 Java 来进行模拟似乎多了一些琐碎的细节,对于具体的为何 Python 和 Js 能如此简介的处理的原理还在琢磨中。此次,也得到了朋友 faberry 的帮助,在一些地方给了意见。

使用OkHttp模拟登陆LeetCode

原文地址:https://www.cnblogs.com/ZhaoxiCheung/p/9302510.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved