LINUX.ORG.RU

Отправить POST на сервер и обойти проверку CORS

 , , , just-for-fun, web-client


0

1

Есть сервис https://baza-otvetov.ru, на котором есть форма викторины https://baza-otvetov.ru/quiz

Сервер отдает на запрос к https://baza-otvetov.ru/quiz страницу html, а после загрузки выполняется следующий javascript-код

<script type="text/javascript">
    function ask(){
        $.ajax({
        cache: false,
        type: "POST",
        url: "/quiz/ask",
        data: {
        },
        beforeSend: function(){
            $(".check").html('<div style="text-align:center;"><img src="/design/images/ajaxloader.gif" /></div>');
        },
        success: function(html){
            $(".check").html(html);
        },
        error: function(){
            $(".check").html('Произошла ошибка, попробуйте обновить страницу.');
        }
        });
    }
    $(document).ready(function () {
        ask();
    });
</script>

Т.е. вопрос с ответами он подгружает POST-запросом к https://baza-otvetov.ru/quiz/ask. Так вот, я никак не могу сэмулировать этот ПОСТ-запрос.


@SpringBootApplication
public class PostrequestApplication implements CommandLineRunner {

	private static final Logger logger = LoggerFactory.getLogger(PostrequestApplication.class);
	private static final String USER_AGENT = "Mozilla/5.0";

    static final String COOKIES_HEADER = "Set-Cookie";
    static java.net.CookieManager msCookieManager = new java.net.CookieManager();


    public static void main(String[] args) {
		SpringApplication.run(PostrequestApplication.class, args);
	}

	@Override
	public void run(String... strings) throws Exception {
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>>>>>> START <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<");

        System.setProperty("sun.net.http.allowRestrictedHeaders", "true");


        HttpsURLConnection get = sendGet("https://baza-otvetov.ru/quiz");
        HttpsURLConnection post = preparePostConnection("https://baza-otvetov.ru/quiz/ask", get);
        sendPost(post);
	}


    private HttpsURLConnection preparePostConnection(String url, HttpsURLConnection get) throws Exception {

        System.out.println("\nGET RESPONSE HEADERS");

        Map<String, List<String>> map = get.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : map.entrySet()) {
            System.out.println("Key : " + entry.getKey() + ", Value : " + entry.getValue());
        }


        System.out.println("POST: "+url);

        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        con.setRequestMethod("POST");

        //set cookies
        Map<String, List<String>> headerFields = get.getHeaderFields();
        List<String> cookiesHeader = headerFields.get(COOKIES_HEADER);

        if (cookiesHeader != null) {
            for (String cookie : cookiesHeader) {
                msCookieManager.getCookieStore().add(null, HttpCookie.parse(cookie).get(0));
            }
        }

        if (msCookieManager.getCookieStore().getCookies().size() > 0) {
            // While joining the Cookies, use ',' or ';' as needed. Most of the servers are using ';'
            con.setRequestProperty("Cookie", join(msCookieManager.getCookieStore().getCookies(), ";"));
        }

        //add reuqest header
        con.setRequestProperty("content-length", "0");
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "ru-RU,ru;q=0.9,en-US;q=0.8,en;q=0.7");
        //con.setRequestProperty("Access-Control-Allow-Origin", "*");
        //con.setRequestProperty("Access-Control-Allow-Credentials", "true");
        con.setRequestProperty("origin", "https://baza-otvetov.ru");
        con.setRequestProperty("referer", "https://baza-otvetov.ru/quiz");

        System.out.println("\nPOST REQUEST HEADERS");
        Map<String, List<String>> map_post = con.getHeaderFields();
        for (Map.Entry<String, List<String>> entry : map_post.entrySet()) {
            System.out.println("Key : " + entry.getKey() + ", Value : " + entry.getValue());
        }


        return con;
    }


    private HttpsURLConnection sendGet(String url) throws Exception {

        System.out.println("GET: "+url);

        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        // optional default is GET
        con.setRequestMethod("GET");

        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);

        int responseCode = con.getResponseCode();
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println(response.toString());

        return con;
	}


    private void sendPost(HttpsURLConnection con) throws Exception {

        // Send post request
        con.setDoOutput(true);

        int responseCode = con.getResponseCode();
        System.out.println("Response Code : " + responseCode);

        BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
        String inputLine;
        StringBuffer response = new StringBuffer();

        while ((inputLine = in.readLine()) != null) {
            response.append(inputLine);
        }
        in.close();

        //print result
        System.out.println("RESPONSE: "+response.toString());

    }


    public static String join(List<HttpCookie> var0, String var1) {
        StringBuffer var2 = new StringBuffer();

        for(Iterator var3 = var0.iterator(); var3.hasNext(); var2.append(var3.next().toString())) {
            if (var2.length() != 0) {
                var2.append(var1);
            }
        }

        return var2.toString();
    }

}

Все равно сервер ничего не возвращает.

Как побороть CORS?

★★★★★

CORS - чисто клиентская технология, это ты должен в своем клиенте предусмотреть обработку соответствующих хидеров.

Попробуй сначала хоть curl'ом сделать нормальный запрос, а потом перенеси его на Java.

hippi90 ★★★★★
()

Вот так работает:

$ curl 'https://baza-otvetov.ru/quiz/ask' -H 'X-Requested-With: XMLHttpRequest'
...
<h3 class='q_id' id='134441'>Как называется самый большой по величине колокол на звоннице Ростовского Кремля?</h3>
<center>
    <table border='0' cellspacing='10'>
        <tr>
            <td><h4>Баран</h4></td>
            <td><h4>Лебедь</h4></td>
        </tr>
        <tr>
            <td><h4>Полиелей</h4></td>
            <td><h4>Сысой</h4></td>
        </tr>
    </table>
</center>%                                                                                                                                                      

Выпадает вопрос с id и ответами. Важно на проверку отдавать ИМЕННО такой ответ, который значится в вариантах, естественно url-кодированный:

$ curl 'https://baza-otvetov.ru/quiz/check' -H 'X-Requested-With: XMLHttpRequest' --data 'q_id=134441&answer=%D0%9B%D0%B5%D0%B1%D0%B5%D0%B4%D1%8C' # Я выбрал "Лебедь"
<h3>Как называется самый большой по величине колокол на звоннице Ростовского Кремля?</h3>
<h3 style='color:#990000'>Не верно!<br /><br /><span style="color:#339966">Правильный ответ: Сысой</span></h3>
<h3>Правильно: 0 из 1<br /><a style='font-size:10px' href="/quiz/clear_results">очистить результаты</a></h3>
<h3><a href='#' onClick="ask(); return false;">еще вопрос</a></h3>%    

anonymous
()

Да и выстави хедер: X-Requested-With: XMLHttpRequest

tyamur ★★
()

И желательно каким нибудь вайршерк пользоваться. Посмотреть что отправляется и принимается.

tyamur ★★
()
Ответ на: комментарий от anonymous

Супер! Спасибо.

Только вот мне их сервер на проверку каждого ответа отдает «Правильно!».

UPD. Мой косяк. ИД вопроса задавал как id, а не как q_id

UPD. Все равно все правильные

bvn13 ★★★★★
() автор топика
Последнее исправление: bvn13 (всего исправлений: 2)
Ответ на: комментарий от bvn13

вот проверка на java:

private boolean checkAnswer(String id, String answer) throws Exception {
        String data = "q_id="+id+"&answer="+ URLEncoder.encode(answer, "utf-8");
        System.out.println("CHECKING: "+data);
        URL obj = new URL("https://baza-otvetov.ru/quiz/check");
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
        con.setDoOutput(true);

        // optional default is GET
        con.setRequestMethod("POST");

        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setUseCaches(false);
        con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        con.setRequestProperty("X-Requested-With", "XMLHttpRequest");

        try(DataOutputStream wr = new DataOutputStream(con.getOutputStream())) {
            wr.write( data.getBytes() );
        }

        int responseCode = con.getResponseCode();
        System.out.println("Response Code : " + responseCode);

        String response = getDataFromConnection(con);

        //print result
        System.out.println("RESPONSE: "+response.toString());

        return response.contains("Правильно!");
    }

bvn13 ★★★★★
() автор топика
Ответ на: комментарий от bvn13

Незачто. Из заголовков можно оставить только X-Requested-With, а запрашивать можно через GET. На будущее, в Firefox'е можно скопировать любой запрос как команду curl - F12->Network, нажимаешь правой кнопкой на запрос, Copy->Copy As cURL.

anonymous
()
Ответ на: комментарий от anonymous

круто, не знал про копирование

bvn13 ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.