Send authentication information with Volley request
Asked Answered
F

3

10

In my Android app I have to call a web service which looks like this

http://mywesite.com/demo/mob/getmenubycategory/1

I am using the volley to send the request but the result is VolleyError 401. I have overridden the getParams() method to add the header, but it is not working.

Here is my code.

RequestQueue requestQueue = volleySingleton.getRequestQueue();
    requestQueue.add(new JsonObjectRequest(Request.Method.GET, url, new Response.Listener<JSONObject>() {
        @Override
        public void onResponse(JSONObject response) {
            Log.e(TAG, "onResponse = \n " + response.toString());
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            Log.e(TAG, "response error \n" + error.networkResponse.statusCode);
        }
    }) {
        @Override
        protected Map<String, String> getParams() throws AuthFailureError {
            try {
                Map<String, String> map = new HashMap<String, String>();
                String key = "Authorization";
                String encodedString = Base64.encodeToString(String.format("%s:%s", "USERNAME", "Password").getBytes(), Base64.NO_WRAP);
                String value = String.format("Basic %s", encodedString);
                map.put(key, value);
                return map;
            } catch (Exception e) {
                Log.e(TAG, "Authentication Filure" );
            }
            return super.getParams();
        }
    });

When I use my browser it shows a dialogue to enter my username and password. How can I send the username and password with the request using Volley.

From answered 16/12, 2015 at 10:55 Comment(6)
Do you have any error log ?Benedictine
no it is simply logging 401 in the onErrorResponse(VolleyError error)From
do you try to print that error?Benedictine
stackoverflow.com/a/23163279Benedictine
Yes i tried but no use. getting only the status codeFrom
Hi! Does my answer work for your question?Some
S
32

For authentication, IMHO, you should override getHeaders instead of getParams, please try the following:

@Override
public Map<String, String> getHeaders() throws AuthFailureError {
       Map<String, String> headers = new HashMap<>();                
       String credentials = "username:password";
       String auth = "Basic "
                        + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
       headers.put("Content-Type", "application/json");
       headers.put("Authorization", auth);
       return headers;
}

Hope it helps!

Some answered 16/12, 2015 at 21:53 Comment(6)
Thanks! Using getHeaders() instead of getParams() solved my problem.Dualpurpose
So this means creating your own Request extension? How do you pass the username:password data and where do the tokens go?Posology
@Posology the question is about basic authentication and as you see in my sample code String credentials = "username:password";, about the tokens, do you mean access token sent to web service? If yes, it's also in getHeaders();Some
@Some I am completely new to doing anything security but this means storing the username and password, putting them in the header, sending them, getting a token and then clearing user/pass out in favor of storing the token then?Posology
@Posology yes, however, it depends on the web service that your android app sending requests, for example, if your web service is ASP.NET Web API, you can see some flows at asp.net/web-api/overview/security/…Some
@Posology please read #31467153Some
M
1

just override this method

 @Override
        public Map<String, String> getHeaders() {
            String username ="[email protected]";
            String password = "dani3173";
            String auth =new String(username + ":" + password);
            byte[] data = auth.getBytes();
            String base64 = Base64.encodeToString(data, Base64.NO_WRAP);
            HashMap<String, String> headers = new HashMap<String, String>();
            headers.put("Authorization",base64);
            headers.put("accept-language","EN");
            headers.put("Content-type","application/json");
            headers.put("Accept","application/json");
            return headers;
        }
Muldrow answered 15/4, 2018 at 11:14 Comment(0)
T
0

Use CustomVolleyRequest as I use below

public class CustomVollyRequest extends Request<JSONObject> {
    private Listener<JSONObject> listener;
    private Map<String, String> params;

    public CustomVollyRequest(String url, Map<String, String> params, 
            Listener<JSONObject> reponseListener, 
            ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    public CustomVollyRequest(int method, String url, Map<String, String> params, 
            Listener<JSONObject> reponseListener, 
            ErrorListener errorListener) {
        super(method, url, errorListener);
        this.listener = reponseListener;
        this.params = params;
    }

    @Override
    protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
        return params;
    }

    @Override
    protected void deliverResponse(JSONObject response) {
        listener.onResponse(response);
    }

    @Override
    protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
        try {
            String jsonString = new String(response.data,     HttpHeaderParser.parseCharset(response.headers));
            return Response.success(new JSONObject(jsonString),
                HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (JSONException je) {
            return Response.error(new ParseError(je));
    }
}

Use the above class as below

Map<String, String> params = new HashMap<>();
params.put("key",value);//put your parameters here
CustomVollyRequest jsObjRequest = new CustomVollyRequest(
        Request.Method.POST, url, params,
        new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                //Log.d("Response: ", response.toString());
            }
        }, 
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError response)
            {
                Log.d("Response: Error", response.toString());
            }
        }
);
Traceable answered 16/12, 2015 at 11:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.