0

Id likes to get HTML from the site. This site has an authentication. Authentication like this:

1) User send POST request with username and password in body 2) Server check users body 3) If username and password are ok, server send 302 with Location header with adress for redirect, where i can get HTML 4) User send POST to link from Location and gets HTML. 5) If username and password are wrong servers also sends 302, but in Location other adress with a form for authentication .

I have a code on JavaScript and its work fine! I want to make same on Android using OkHTTP 3.8.1 but i cant, all time i get `200 OPTIONS. Here is fine my JavaScript code:

var data = "auth-type=mo&username=SECRET&password=SECRET";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://lk.mango-office.ru/auth");
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
xhr.send(data);

Here is my wrong OkHTPP code:

public class MainActivity extends AppCompatActivity
{
    public String postUrl = "https://lk.mango-office.ru/auth";
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        try
        {
            postRequest(postUrl, "auth-type=mo&username=SECRET&password=SECRET" );
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    void postRequest(String postUrl, String postBody) throws IOException
    {
        String str = postBody;
        OkHttpClient client = new OkHttpClient();
        RequestBody body = RequestBody.create(mediaType, postBody);
        Request request = new Request.Builder()
            .url("https://lk.mango-office.ru/auth")
            .post(body)
                .addHeader("Content-Type", "application/x-www-form-urlencoded")
                .build();

        client.newCall(request).enqueue(new Callback()
        {
            @Override
            public void onFailure(Call call, IOException e)
            {
                call.cancel();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException
            {
                Log.d("TAG", response.body().string());
            }
        });
    }
}
Masquitos
  • 554
  • 4
  • 22

2 Answers2

1

postbody should be like this

JSONObject body = new JSONObject();

body.put("auth-type", "mo");
body.put("username", "SECRET");
body.put("password", "SECRET");

then replace the "postbody" with the "body" of the jsonobject

RequestBody body = RequestBody.create(mediaType, body.toString());

then remove the

.addHeader("Content-Type", "application/x-www-form-urlencoded")
Bryan
  • 337
  • 1
  • 12
  • @Vryin Sorry i do not understand. U said i have to create JSONObject , its ok. Then U said i have to pass this JSONObject to RequestBody.create(). But i get an errod, cause RequestBody.create() cant use JSONObject . – Masquitos Aug 04 '17 at 11:04
  • @Vryin now its compiling, but still doesnt work right, like JavaScript code – Masquitos Aug 04 '17 at 11:33
  • have you tried adding this to your media type? ; charset=utf-8 like MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8"); – Bryan Aug 04 '17 at 11:40
  • i change to "MediaType.parse("application/x-www-form-urlencoded; charset=utf-8")" still doesnt work. – Masquitos Aug 04 '17 at 12:00
  • When i use JavaScript code in Crome, server send me response 302, for my request. This response has header "Location" with new adress. When i use Android code, server also send me 302 response, but there no new adress. – Masquitos Aug 05 '17 at 08:16
  • The response of the network is 200 and 302, means that it's processing correctly. However, you will need the new address from the 302 response body, you're almost there buddy. – Bryan Aug 07 '17 at 04:59
  • i found an a problem. in 302 response server send me a Cookie. I have to send other requset with that Cookie. Can u help me ho to get them, add to new requset and send new requset ? – Masquitos Aug 07 '17 at 08:52
  • I think this would help you regarding your cookie problem. https://stackoverflow.com/questions/35743291/add-cookie-to-client-request-okhttp And if my answer helped you, you can mark this answer as the correct answer. – Bryan Aug 07 '17 at 09:15
  • thx. the problem was in a cookies. not in my task code. i Ovverride `saveFromResponse` ,`loadForRequest` from [this code](https://stackoverflow.com/a/35743688/7160632) and add `ArrayList cookieFromServer = new ArrayList<>(); public void saveCookie(List cookies) { for (int i = 0; i < cookies.size(); i++) { String str = cookies.get(i).toString(); if (str.indexOf("issa7=") != -1) { cookieFromServer.add(cookies.get(i)); Log.d("TAG", cookies.get(i).toString()); } } }` now ts ok – Masquitos Aug 07 '17 at 13:10
  • 1
    Way to go buddy. – Bryan Aug 08 '17 at 04:20
0

You can try below code for authorization:

OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        Request original = chain.request();

                        String credentials = "username" + ":" + "password";
                        final String basic =
                                "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
                        Request.Builder requestBuilder = original.newBuilder()
                                .header("Authorization", basic);

                        Request request = requestBuilder.build();
                        return chain.proceed(request);
                    }
                }).build();
nivesh shastri
  • 430
  • 2
  • 13