So I'm running into a problem when calling rest-auth/user/.
I am able to login and obtain the key from said login, but from that I'm not sure how to use it in regards to rest-auth/user/. I've tried using it with GET in volley, as well as POSTing it in volley. But everytime I try to do so, I get a 403 back saying credentials were not provided. I've also tried saving the token to Android's SharedPreferences.
I'm not sure what could be wrong or how to fix this problem, so any help would be appreciated.
My code looks like this:
getUserQueue = Volley.newRequestQueue(this);
JSONObject jsObj = new JSONObject();
try {
jsObj.put("token", token);
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, "http://hurst.pythonanywhere.com/supportal/rest-auth/user/", jsObj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
result = response.getString("username");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
// add the request object to the queue to be executed
getUserQueue.add(jsObjRequest);
From comments it is clear that you are using different authentication schemes for rest, will explain these,
SessionAuthentication
For authenticating session authentication you need persistant cookie implementation in android volley, check here for this, where Set-Cookie header is parsed from server api response & send over next requests.
BasicAuthentication
In Basic authentication scheme, username & password are send over every request ( after login ?), with Authorization header value ( Base64 encoded).To check how to implement this check here
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String creds = String.format("%s:%s","USERNAME","PASSWORD");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
params.put("Authorization", auth);
return params;
}
JSONWebTokenAuthentication
In JWT authentication scheme, after successful login you will get a JWT token, you need to send this token in every request that need user authorization, for this to work, set Authorization header value with JWT token_after_login;Only difference with Basic authentication is how header is send.
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String auth = "JWT " + token // token you will get after successful login
params.put("Authorization", auth);
return params;
}
Related
Peeps, I have some problem in understanding the working of volley library, so answer with proper material which can guide me to unobserved aspects of volley is what I am looking forward to.
How does my POST parameters are bind in network request. When I send params after overriding getParams() and by sending jsonObject directly in network request I don't receive any response but some server errors.
Since I am testing my backend on Postman, what postman actually does(my Observation) is it bind the params in url itself. When I copy paste the url in my android code it responds positively.
So, should I code to append my params to url or there's another way round?
I have alredy tried making changes to getHeaders() but it doesn't respond too!
You should use a JsonObjectRequest with a jsonObject containing all your params.
HashMap<String, String> params = new HashMap<String, String>();
params.put("token", "8327483274823");
JSONObject jsonObject = new JSONObject(params);
JsonObjectRequest req = new JsonObjectRequest(URL,jsonObject ,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
//Do stuff here
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//Handle Errors here
}
});
I have teaching myself how to develop Android applications and I recently started using the Volley library for networking. I have been able to send basic requests with it. I was experimenting with Pocket's API to see if my app could fetch the items. Their documentation page mentions that I have to send a JSON request like so
POST /v3/oauth/request HTTP/1.1
Host: getpocket.com
Content-Type: application/json; charset=UTF-8
X-Accept: application/json
{"consumer_key":"1234-abcd1234abcd1234abcd1234",
"redirect_uri":"pocketapp1234:authorizationFinished"}
So I made a JSONObject in my app, added the key consumer_key with the value of my consumer key, then added in the key redirect_uri with its respective value. I sent this JSONObject as a request to the required URL as a POST request using Volley. The response code I received was 403, which is caused by a bad consumer key. I have double-checked the consumer key, so the problem lies with my request. How should I go about making the JSON request? Do I have to add the extra data, like Content-Type? If so, how?
If it is not too much, could you point me to a beginner-friendly resource on JSON, since I do not have much knowledge about web development?
Thank you.
What request methode do you use on your code? I am facing issue when using StringRequest method. Its work when use JsonObjectRequest method.
Here is how to create request besides on my experience.
Create Header Parameter
final Map<String, String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/json");
headers.put("X-Accept", "application/json");
headers.put("consumer_key", "your-consumer-key");
headers.put("redirect_uri", "https://kamus.nusagates.com");
Create JSONObject From headers
JSONObject obj = new JSONObject(headers);
Create JsonObjectRequest
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest("https://getpocket.com/v3/oauth/request", obj, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//get all response data
Log.d("respon", String.valueOf(response));
try {
//get code from response
Log.d("respon code", response.getString("code"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
return headers;
}
#Override
protected Response<JSONObject> parseNetworkResponse(NetworkResponse response) {
String server = String.valueOf(response.headers);
Log.d("header", server);
return super.parseNetworkResponse(response);
}
};
Add the request to The Queue
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
queue.add(jsonObjectRequest);
May this could help you solve your problem.
Cheers
I am using JWT to manage server authentication for my application. I manage it in the server. In my angular app, I am using angular-jwt to manage jwt. If it expired how to call refresh token API. I am using volley for API call. When the token is expired the server responds with 401 error code. That time needs to call a refresh token api. After refresh call, i need to call the previous API call again without any user input.
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(method, request_url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
if (response.getInt("status") == 1) {
callback.onSuccessResponse(response.get("data"));
} else {
callback.onSuccessResponse(new JSONArray());
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
if (networkResponse != null && networkResponse.statusCode == 401) {
}
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> headers = new HashMap<String, String>();
String token = AppPreferencesHelper.getAccessToken(context);
headers.put("Authorization", "Bearer " + token);
return headers;
}
};
Volley.newRequestQueue(context).add(jsonObjectRequest);
You need to call api to validate token, if its expired than you can generate new.
Or if you have login feature than you can check for JWT in login and generate new if old expired.
I have use a very basic way in my app, I am creating a JWT using a unique email address per user and stores it into database in server and it never expires. Whenever a user logout, I remove the JWT and when login again I generate new token.
I'm trying to make a GET request in an Android application using the Volley library. This GET request is to verify account credentials using Basic HTTP Authentication. I verified the URL with credentials works in my browser as it returns successful XML. The format is:
http://username:password#myanimelist.net/api/account/verify_credentials.xml
where username and password obviously represent real user credentials. Volley throws this error:
BasicNetwork.performRequest: Unexpected response code 401 for http://username:password#myanimelist.net/api/account/verify_credentials.xml
Here is my Android code that handles the request:
private static final String HTTP_PRE = "http://";
private static final String VERIFY_CREDENTIALS = "myanimelist.net/api/account/verify_credentials.xml";
public void verifyCredentials(String username, String password) {
RequestQueue queue = Volley.newRequestQueue(context);
String url = HTTP_PRE + username + ":" + password + "#" + VERIFY_CREDENTIALS;
StringRequest stringRequest = new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
processResponse(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// handle error
Log.d(TAG, "error: " + error.getMessage());
}
});
queue.add(stringRequest);
}
This solution to override the getHeaders() method provided the same result:
How does one use Basic Authentication with Volley on Android?.
Here is my implementation of that solution:
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = super.getHeaders();
if (params == null){
params = new HashMap<>();
}
String creds = String.format("%s:%s", username, password);
params.put("Authorization", creds);
return params;
}
Which returned this error without the credentials built directly into the URL:
BasicNetwork.performRequest: Unexpected response code 401 for http://myanimelist.net/api/account/verify_credentials.xml
If someone could provide advice, I'd really appreciate it. This is my first time using Basic HTTP Authentication so I could be missing something obvious.
I solved this problem following the first answer here: Http Authentication in android using volley library. I had tried something similar and many other solutions but this was the only one that worked.
Basic Authentication uses BASE64 encoding. You're missing
String creds = String.format("%s:%s", username, password);
creds = Base64.encodeToString(creds.getBytes(), Base64.NO_WRAP);
The Authorization HTTP header requires to indicate the method used (Basic|Digest). At last you headers should look like this:
GET http://username:password#myanimelist.net/api/account/verify_credentials.xml
Accept: text/xml,text/plain
...
Authorization: Basic XXXXXXXXXXXXXX==
I am trying to sent JSON format data (using Volley) from two EditText-views and a method that return unique Device ID to a URL from my Android application and I receive
"[8970] BasicNetwork.performRequest: Unexpected response code 401 for https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook"
Here is My method:
private void doPost() {
final String url = "https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook";
final String deviceId = getDeviceId(getApplicationContext());
try {
try {
JSONObject jsonObject = new JSONObject();
String title = editTitle.getText().toString();
String content = editContent.getText().toString();
jsonObject.put("title", title);
jsonObject.put("content", content);
jsonObject.put("deviceId", "<" + deviceId + ">");
} catch (JSONException e) {
e.printStackTrace();
}
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.POST,
url, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Log.e("VOLLEY", "ERROR");
}
});
requestQueue.add(jsonObjectRequest);
} catch (Exception e) {
e.printStackTrace();
}
}
it should be in a format :
{
"title":"Birth day",
"content":"Buy a gift for my mom!",
"deviceId":"<Device ID>"
}
A 401 is an Unauthorized error.
https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error
This means that the user and password is not getting recognized. You're providing it by means of the URL, but this only works for the browser. If the service you're using accepts Basic HTTP authorization headers, this code will provide you the needed headers:
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
String creds = String.format("%s:%s","USERNAME","PASSWORD");
String auth = "Basic " + Base64.encodeToString(creds.getBytes(), Base64.DEFAULT);
params.put("Authorization", auth);
return params;
}
Original code from https://stackoverflow.com/a/18980454/3286819
Of course, username and password needs to be your own. In this case:
username: gorountsiallyetlasornall
password: 5wxGq5UNlY6wdWmNAyYPVVrN
URL: https://bulberadev.cloudant.com/notebook (notice I've removed the user and password)
Some more info: https://yakivmospan.wordpress.com/2014/04/04/volley-authorization/
Error 401 is an HTTP error for unauthorised. This is not a Volley or android related fault. In this case the URL you have provided
https://gorountsiallyetlasornall:5wxGq5UNlY6wdWmNAyYPVVrN#bulberadev.cloudant.com/notebook
Cannot be interpreted by Volley as a login either. This url is sometimes used by cURL and other tools to hardcode the username in password into the URI for Basic Authentication HTTP.
For this your username is gorountsiallyetlasornall and your password is 5wxGq5UNlY6wdWmNAyYPVVrN.
According to Basic Autentication, explained https://luckymarmot.com/paw/doc/HTTP_Basic_Auth
It needs to be converted to Base 64 then added to the header of the request.
I have converted your username and password into a Basic Auth base 64 encoded String for you bellow.
Z29yb3VudHNpYWxseWV0bGFzb3JuYWxsOjV3eEdxNVVObFk2d2RXbU5BeVlQVlZyTg==
Add this into your Volley header by extending a Volley request and overriding the function getHeaders to return a HashMap with the following key value pair.
"Authorization" , "Basic Z29yb3VudHNpYWxseWV0bGFzb3JuYWxsOjV3eEdxNVVObFk2d2RXbU5BeVlQVlZyTg"
Your request will now work.
Please let me know if you want a more detailed explanation.
PS. Hopefully the values you posted in your question is not your real username and password. If so, then don't do that in the future.