I'm following the OAuth 1.0 Protocol so I can send an Authenticated Request to /oauth/identity Endpoint as in step 5 of the Auth flow.
From the doc, making request involves including several params as you can see here.
What my requests looks like is :
http://api.discogs.com/oauth/identity?
oauth_consumer_key=CONSUMER_KEY&
oauth_nonce=1453720099377&
oauth_signature=CONSUMER_SECRET&ACCESS_TOKEN_SECRET&
oauth_signature_method=PLAINTEXT&
oauth_timestamp=1453720099377&
oauth_token=ACCESS_TOKEN
where ACCESS_TOKEN and ACCESS_TOKEN_SECRET derive from step 4 of the Auth Flow guide and
CONSUMER_SECRET and CONSUMER_KEY from my Discogs developer settings.
What my code looks in Java, since this is for an android Discogs client :
public void getIdentity() {
httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded");
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("OAuth oauth_consumer_key=\"").append(Constants.CONSUMER_KEY).append("\",");
stringBuilder.append("oauth_nonce=\"").append(String.valueOf(System.currentTimeMillis())).append("\",");
stringBuilder.append("oauth_signature=\"").append(Constants.CONSUMER_SECRET).append(authAccessSecretToken).append("\",");
stringBuilder.append("oauth_signature_method=\"PLAINTEXT\",");
stringBuilder.append("oauth_timestamp=\"").append(String.valueOf(System.currentTimeMillis())).append("\",");
stringBuilder.append("oauth_token=\"").append(authAccessToken).append("\"");
httpClient.addHeader("Authorization", stringBuilder.toString());
httpClient.addHeader("User-Agent", "Discs/1.0 +https://jb.com");
httpClient.get(identityURL, null, new TextHttpResponseHandler() {
#Override
public void onFailure(int i, Header[] headers, String s, Throwable throwable) {
Log.d(TAG, "onFailure IDENTITY " + i + " Throwable = " + throwable);
Log.d(TAG, "onFailure IDENTITY " + s);
}
#Override
public void onSuccess(int i, Header[] headers, String s) {
Log.i(TAG, "onSuccess IDENTITY -- String= " + s);
}
});
}
But what I get is : {"message": "You must authenticate to access this resource."}
Using an OAuth library instead of generating these requests manually will likely save you a headache. more information read https://www.rfc-editor.org/rfc/rfc5849#page-14
Related
The FCM Token ID has been generated and I want it to send to the PHP server and then store it in a variable. What should be the approach?
#Override
public void onNewToken(String token) {
Log.d(TAG, "Refreshed token: " + token);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(token);
}
private void sendRegistrationToServer(String token) {
}
PHP Code
<?php
$token = $_POST["tokenid"];
echo ($token);
?>
You can store you FCM-Id in Preference and then pass this FCM-Id to backend pass it as a parametr using API calling. here below i'm get FCM-Id and pas to PHP using API.
MyFirebaseInstanceIDService.java
public class MyFirebaseInstanceIDService extends FirebaseInstanceIdService {
private static final String TAG = "MyFirebaseIIDService";
Context context;
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. Note that this is called when the InstanceID token
* is initially generated so this is where you would retrieve the token.
*/
// [START refresh_token]
#Override
public void onTokenRefresh() {
// Get updated InstanceID token.
String refreshedToken = FirebaseInstanceId.getInstance().getToken();
Log.d(TAG, "Refreshed token: " + refreshedToken);
context = getApplicationContext();
AppPreference.setStringPref(context, AppPreference.PREF_SIGNUP_FCM_ID, AppPreference.PREF_KEY.PREF_KEY_FCM_ID,
refreshedToken);
// If you want to send messages to this application instance or
// manage this apps subscriptions on the server side, send the
// Instance ID token to your app server.
sendRegistrationToServer(refreshedToken);
}
// [END refresh_token]
/**
* Persist token to third-party servers.
* <p>
* Modify this method to associate the user's FCM InstanceID token with any server-side account
* maintained by your application.
*
* #param token The new token.
*/
private void sendRegistrationToServer(String token) {
// TODO: Implement this method to send token to your app server.
Map<String, String> params = new HashMap<String, String>();
String device_id = Common.getDeviceId(this);
params.put(FCM_TOKEN, token);
params.put(DEVICEID, device_id);
params.put(DEVICE_TYPE, device_type);
JsonObjectRequest request = new JsonObjectRequest(FCM_TOKEN_URL, new JSONObject(params),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
parseJsonPersonalDetail(response);
} catch (Exception e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error.networkResponse != null) {
int statusCode = error.networkResponse.statusCode;
NetworkResponse response = error.networkResponse;
Log.d("testerror", "" + statusCode + " " + response.data);
}
}
}) {
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<String, String>();
headers.put("User-agent", "Mozilla/5.0 (TV; rv:44.0) Gecko/44.0 Firefox/44.0");
return headers;
}
};
Common.setVolleyConnectionTimeout(request);
ApplicationClass.getInstance().getRequestQueue().add(request);
}
/**
* <b>Description</b> - Get back response for calling callUserDetailSave API
*
* #param jsonObject - Pass API response
*/
private void parseJsonPersonalDetail(JSONObject jsonObject) {
try {
Log.i("get response", "get response" + jsonObject);
if (jsonObject.toString().contains(Constant.JSON_KEY.MSG)) {
String message = jsonObject.getString(Constant.JSON_KEY.MSG);
String status = jsonObject.getString(Constant.JSON_KEY.CODE);
}
} catch (Exception e) {
e.getStackTrace();
}
}
}
Here first i'm get FCM id then call API method sendRegistrationToServer and pass token in API as a paramter so back-end developer get this token from API parameter.
Here i'm pass three parameters
params.put(FCM_TOKEN, token);
params.put(DEVICEID, device_id);
params.put(DEVICE_TYPE, device_type);
device_id and device_type pass because it's my requirment.
Add dependency in app level gradle file for calling Volley API call :
implementation 'com.android.volley:volley:1.1.0'
Checkout i'm created Demo for you: Demo
Volley Libraries Example :
Tutorial 1
Tutorial 2
Tutorial 3
I'm want to consume share point rest API service to call from Android previously i use to call share point web service through the graph API but while generating token from graph API its not support in below URL, does any one have any solution about this problem.
https://mysharepoint.sharepoint.com/sites/MySite/_api/web/lists/getbytitle('Announcements')/Items
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, MSGRAPH_URL,
parameters,new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
/* Successfully called graph, process data and send to UI */
Log.d(TAG, "Response: " + response.toString());
updateGraphUI(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error: " + error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", "Bearer " + authResult.getAccessToken());
return headers;
}
};
Log.d(TAG, "Adding HTTP GET to Queue, Request: " + request.toString());
request.setRetryPolicy(new DefaultRetryPolicy(
3000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
queue.add(request);
I already tried with MSAL library but its does not work with this token.
Update: i used to call graph api for janrating token but i got 401 error with this above mention URL.
You are calling a SharePoint API, so you will need a SharePoint token instead of a Graph token. These are two separate APIs with different authentications.
To get a SharePoint token you will need to register an App in SharePoint itself or use the users username + password if available in your app.
Also see:
https://spshell.blogspot.com/2015/03/sharepoint-online-o365-oauth.html
https://shareyourpoint.net/2017/01/25/operations-using-rest-in-sharepoint-online-authorization/
For Graph, use an URL like this to get your list items:
https://graph.microsoft.com/v1.0/sites/{site-id}/lists/{list-id}/items?expand=fields(select=Column1,Column2)
You will probably need to do several calls to get your site ID and list ID first.
https://learn.microsoft.com/en-us/graph/api/listitem-list?view=graph-rest-1.0
Hello I'm trying to build a Clima app and I'm Using OpenWeatherMap Api
to retrieve weather data from the internet.
When I try the app on a physical device, I got this message error:
cz.msebera.android.httpclient.client.HttpResponseException: Unauthorized
I tried to generate a new API key but the same problem.
// TODO: Add letsDoSomeNetworking(RequestParams params) here:
protected void letsDoSomeNetworking(RequestParams params) {
AsyncHttpClient client = new AsyncHttpClient();
client.get(WEATHER_URL, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode ,Header[] header , JSONObject response){
Log.d("Clima", "onSuccess: " + response.toString());
}
public void onFailure (int statusCode , Header[] headers , Throwable e , JSONObject response){
Log.d("Clima", "Onfailure: " + statusCode);
Log.d("Clima", "fail: " + e.toString());
Toast.makeText(WeatherController.this, "requestFialed " , Toast.LENGTH_SHORT).show();
}
});
}
i think it s highly like you didn't change this variable
final String APP_ID = "e****************************a"; on the weathercontroller.java
you're supposed to write yout own app_id , you can your own key by signing up at
http://api.openweathermap.org/ , you will get the app_id on your email and the key will be activated within 1hour or 2 . best of luck buddy!
I am working in an android application that has to send user email through post method. The api endpoint is at https://api-iddog.idwall.co/ when i already run some tests and was able to GET values from here. Im using Loopj Library.
However, i've been tasked with using this endpoint:
https://api-iddog.idwall.co/signup
The documentation guide shows that i need to construct the POST method using the following parameters:
using Content-Type: application/json header
and the post URL should be something like:
Api Post Doc
With all that in mind, i got the create a method called attempPost(). On this method im creating the AsyncHttpRequest object, RequestParams object and storing the valid e-mail typed by the user.
private void attempPost() {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
String url = "https://api-iddog.idwall.co/signup";
String userEmail = userEmailView.getText().toString();
JSONObject jsonEmail = new JSONObject();
try {
jsonEmail.put("email", userEmail);
} catch (JSONException e) {
e.printStackTrace();
}
Log.d("Dog", " " + jsonEmail.toString());
params.put("-d", jsonEmail);
client.addHeader("Content-Type", "application/json");
client.post(url, params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.d("Dog", "onSucess" + responseBody.toString());
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.e("Dog", "" + error.toString());
}
});
}
This method is called in a OnclickListener, and the log is returning a message called BadRequest and Status Code 400. I already tried to apply some code examples from Loopj doc but i didnt work. Can someone give me an insight in what i am doing wrong ? From what i can gather the success response should be a String(Token) and i need this token to complete the project.
EDIT.
I worked a little more through documentation and other examples here on Stack and i found this: POSTing JSON/XML using android-async-http (loopj)
In the accepted answer there is an example on how to post JSON.
Then i made a few changes in my attempPost method.
private void attempPost() {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
String url = "https://api-iddog.idwall.co/signup";
String userEmail = userEmailView.getText().toString();
JSONObject jsonParams = new JSONObject();
try {
jsonParams.put("email", "your#email.com");
} catch (JSONException e) {
e.printStackTrace();
}
client.post(getApplicationContext(), url, jsonParams, "application/json", new AsyncHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
Log.d("Dog", "onSucess" + responseBody.toString());
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Log.e("Dog", "" + error.toString());
Log.e("Dog", "status code " + String.valueOf(statusCode));
}
});
}
But Android Studio is telling me to convert jsonParams into a entity. In the example i got from stack its uses the following code to achieve that:
StringEntity entity = new StringEntity(jsonParams.toString());
However my android studio gets an horror that says:
Unhandled exception : java.io.UnsupportedEncodingException,
Until this moment i could not figure a way to solve this.
I managed to make it work, the API its now returning a proper response and status code 200. I converted the JsonObject into a ByteArrayEntity since the StringEntity was not an option.
private void attempPost() {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
String userEmail = userEmailView.getText().toString();
JSONObject jsonParams = new JSONObject();
try {
jsonParams.put("email", userEmail);
} catch (JSONException e) {
e.printStackTrace();
}
ByteArrayEntity be = new ByteArrayEntity(jsonParams.toString().getBytes());
//TODO create a class to handle JSON post, getmethods and parse token value
client.post(getApplicationContext(), API_URL, be, "application/json", new JsonHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
Log.d("Dog", "onSucess " + response.toString());
Log.d("Dog", "status code " + String.valueOf(statusCode));
}
#Override
public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) {
super.onFailure(statusCode, headers, throwable, errorResponse);
Log.e("Dog", "" + errorResponse.toString());
Log.e("Dog", "status code " + String.valueOf(statusCode));
}
});
}
I'm writing an android application which uses rest services for user regitration and more but running into trouble with my login service. for some reason the requestparams i put into my service call on android side are not being found within my rest service.
could anny 1 tell me what i'm doing wrong or link to a guide which explains how to solve this problem?
Relevant android functions:
public void loginUser(View view) {
// Get username and password values
String username = usernameEdit.getText().toString();
String password = passwordEdit.getText().toString();
// Instantiate Http Request Param Object
RequestParams params = new RequestParams();
// Check if username & password is not null
if(Utility.isNotNull(username) && Utility.isNotNull(password)) {
// Http parameters
params.put("username", username);
params.put("password", password);
invokeWS(params);
} else {
Toast.makeText(getApplicationContext(), "Vul een gebruikersnaam en of " +
"wachtwoord in", Toast.LENGTH_LONG).show();
}
}
// Method that performs RESTful webservice invocations
public void invokeWS(RequestParams params) {
// Make RESTful webservice call using AsyncHttpClient object
AsyncHttpClient client = new AsyncHttpClient();
client.post("http://10.0.2.2:8080/NTR_application/rest/session", params, new AsyncHttpResponseHandler() {
// When the response returned by REST has Http response code '200'
#Override
public void onSuccess(String response) {
Toast.makeText(getApplicationContext(), "You are successfully logged in!" + response, Toast.LENGTH_LONG).show();
// Gets an JSON object with user Data
// Write user Data to SQLite
User user = new Gson().fromJson(response, User.class);
db.addUser(user);
// Navigate to Home screen
navigatetoHomeActivity();
}
// When the response returned by REST has Http response code other than '200'
#Override
public void onFailure(int statusCode, Throwable error,
String content) {
Toast.makeText(getApplicationContext(), "ERROR!" + content + error + statusCode, Toast.LENGTH_LONG).show();
}
});
}
and the rest services which is called :
#Path("/session")
public class UserService {
private Controller controller = new Controller();
#POST //Post so you can't see the information in the browser history easily
#Produces(MediaType.APPLICATION_JSON)
public Response authenticate(#QueryParam("username") String username, #QueryParam("password") String password){
User user = null;
try {
user = controller.authenticate(username, password);
} catch (NoSuchAlgorithmException | SQLException e) {
System.out.println("Authentication caught an exception; failed for: " + username);
e.printStackTrace();
}
if (user != null){
String json = new Gson().toJson(user);
return Response.status(200).entity(json).build();
} else {
return Response.status(401).entity("Username and/or password is incorrect").build();
}
}
}
Mistake was obvious once i saw it, since i use a #POST i need to use #FormParam instead of #QueryParam.
tutorial i used to write these methods used #GET to login which is insecure.