Add parameter into body with Scribe Library - android

I'm developing an Android app and I have integrated Scribe library to make http connection with OAuth1.0 with Magento. My problem is that I need to send a request with a parameter into body but without a key. Now I make login correctly and I have my Token authorized, I get products from server, categories, blah blah... but I cannot make checkout because always I get code "401 Authorization require". I think that the problem could be by the parameter in the body.
My code:
...
#Override
protected String doInBackground(String... json) {
String result = null;
org.scribe.model.Response response = null;
String url = Global.BASE_URL + "cart/1";
if(Global.TOKEN_AUTHORIZED != null) {
OAuthRequest request = new OAuthRequest(Verb.POST, url);
//I only need insert a json into body without key
request.addBodyParameter(<I don't need a key>, json[0]);
Global.OAUTH_SERVICE.signRequest(Global.TOKEN_AUTHORIZED, request);
response = request.send();
}
if(response != null && response.getCode() == 200) {
result = response.getBody();
} else {
result = "ERROR";
}
return result;
}
...
How I put only a parameter in the body but without key, value?
Thanks in advance :)

I found the solution:
First is necessary to add a Header to say that content of the request is a json
To add a single parameter into the body without key, value exists a method called addPayload(String)
Now I get a response with code 200 :)
if(Global.TOKEN_AUTHORIZED != null) {
OAuthRequest request = new OAuthRequest(Verb.POST, url);
request.addHeader("Content-Type", "application/json");
request.addPayload(params[0]);
Global.OAUTH_SERVICE.signRequest(Global.TOKEN_AUTHORIZED, request);
response = request.send();
}
I hope to help somebody :)

Related

Spring Rest : Handling POST requests, at server end

I am asking this question based on the answers in this link
POST request via RestTemplate in JSON
I actually wanted to send JSON from client and receive the same at REST server. Since the client part is done in the link I mentioned above. For the same how would I handle that request at server end.
CLIENT:
// create request body
JSONObject request = new JSONObject();
request.put("username", name);
request.put("password", password);
// set headers
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<String>(request.toString(), headers);
// send request and parse result
ResponseEntity<String> loginResponse = restTemplate
.exchange(urlString, HttpMethod.POST, entity, String.class);
if (loginResponse.getStatusCode() == HttpStatus.OK) {
JSONObject userJson = new JSONObject(loginResponse.getBody());
} else if (loginResponse.getStatusCode() == HttpStatus.UNAUTHORIZED) {
// nono... bad credentials
}
SERVER:
#RequestMapping(method=RequestMethod.POST, value = "/login")
public ResponseEntity<String> login(#RequestBody HttpEntity<String> entity) {
JSONObject jsonObject = new JSONObject(entity.getBody());
String username = jsonObject.getString("username");
return new ResponseEntity<>(username, HttpStatus.OK);
}
This gives me 400 bad request error at client side. Hoping for some clues about how to handle this at server side.
HTTPEntity should not be used in your server method. Instead use the argument which is being passed to HTTPEntity from your client. In your case it has to String since you are passing string from client. Below code should work for you.
#RequestMapping(method=RequestMethod.POST, value = "/login")
public ResponseEntity<String> login(#RequestBody String jsonStr) {
System.out.println("jsonStr " + jsonStr);
JSONObject jsonObject = new JSONObject(jsonStr);
String username = jsonObject.getString("username");
return new ResponseEntity<String>(username, HttpStatus.OK);
}
My advice is to create bean class and use it in server and client instead of converting it to String. It will improve readability of the code.
When using the Spring RestTemplate, I usually prefer to exchange objects directly. For example:
Step 1: Declare and define a data holder class
class User {
private String username;
private String password;
... accessor methods, constructors, etc. ...
}
Step 2: Send objects of this class to the server using RestTemplate
... You have a RestTemplate instance to send data to the server ...
// You have an object to send to the server, such as:
User user = new User("user", "secret");
// Set HTTP headers for an error-free exchange with the server.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
// Generate an HTTP request payload.
HttpEntity<User> request = new HttpEntity<User>(user, headers);
// Send the payload to the server.
restTemplate.exchange("[url]", [HttpMethod], request, User.class);
Step 3: Configure a ContentNegotiatingViewResolver on the server
Declare a bean of the type ContentNegotiatingViewResolver in the Spring XML or Java configuration. This will help the server automatically bind HTTP requests with bean objects.
Step 4: Receive the request on the server
#RestController
#RequestMapping("/user")
class UserAPI {
#RequestMapping(method = RequestMethod.POST)
#ResponseBody
public User create(User user) {
// Process the user.
// Possibly return the same user, although anything can be returned.
return user;
}
}
The ContentNegotiatingViewResolver ensures that the incoming request gets translated into a User instance without any other intervention.
Step 5: Receive the response on the client
// Receive the response.
HttpEntity<User> response = restTemplate.exchange("[url]", [HttpMethod], request, User.class);
// Unwrap the object from the response.
user = response.getBody();
You will notice that the client and the server both use the same bean class (User). This keeps both in sync as any breaking change in the bean structure would immediately cause a compilation failure for one or both, necessitating a fix before the code is deployed.

Android Studio app using Django back-end login authentication?

I've recently been working on an Android app using Android Studio which is using a Django backend. The web application is already in place I just want to make the app in Android for it.
The problem I am running in to, which is mostly because I'm new to app development, is the login authentication. I've researched on this topic here and I understand theoretically how I should go about doing this, but I have not been successful in logging in from my app.
The problem I have is this:
I get a csrf token authentication failure. It states that the cookie is not set. I understand that a post request will return this.
I am always getting a success transition in my doPost method.
I currently am lost in how to check if I have actually logged in or not. And the only solution I thought of for the cookie not being set is to do a Get request, parse the cookie as a string and pass that in to the post request. But I'm not sold on it being the best strategy. The bigger problem is not being able to tell if I have actually logged in or not. How can I check that? I have read posts on kind of explaining how to do this but as a beginner it is hard to translate that to code. How do I check if the user was actually authenticated? Any and all help is appreciated.
public class UserLoginTask extends AsyncTask<Void, Void, Boolean> {
private final String mEmail;
private final String mPassword;
UserLoginTask(String email, String password) {
mEmail = email;
mPassword = password;
}
#Override
protected Boolean doInBackground(Void... params) {
ArrayList<NameValuePair> postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("username", mEmail));
postParameters.add(new BasicNameValuePair("password", mPassword));
String response = null;
String get_response = null;
try
{
response = SimpleHttpClient.executeHttpPost(localLoginUrl, postParameters);
Log.d("Login Activity","Post Response is: " + response);
}
catch (Exception e)
{
Log.d("Login Activity","Error is: " + e.toString());
e.printStackTrace();
return false;
}
return true;
}
public static String executeHttpPost(String url,
ArrayList<NameValuePair> postParameters) throws Exception {
BufferedReader in = null;
try {
HttpClient client = getHttpClient();
HttpPost request = new HttpPost(url);
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
request.setEntity(formEntity);
HttpResponse response = client.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line = "";
String NL = System.getProperty("line.separator");
while ((line = in.readLine()) != null) {
sb.append(line + NL);
}
in.close();
String result = sb.toString();
return result;
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
The Django view:
def login_view(request): # Login page view
form = login_form()
if request.method == 'POST':
form = login_form(request.POST)
if form.is_valid(): # check if form is valid
user = authenticate(
username=form.cleaned_data['username'],
password=form.cleaned_data['password']) # authenthicate the username and password
login(request, user) # login the user
# Once logged in redirect to home page
response = HttpResponseRedirect("/"+some_user_url+"/home")
print "USER KEY IS: %s" % some_user_key
response.set_cookie('some_user_key', value=some_user_value, max_age=some_max_age, secure=SESSION_COOKIE_SECURE, httponly=False)
return response
else:
form = login_form() # Display empty form
return render(request, "login.html", { # loads the template and sends values for the template tags
'form': form,
})
I know the questions was asked quite a long time ago but, since there's no answer, and I'm working quite intensively with Django recently, I thought to share my very basic knowledge, hoping it will be of help for others.
The way you are dealing with the CSRF token is the correct one: first you perform a get of the login page which will give you the CSRF token in the cookie. You store the cookie and the CSRF token and you embed them in the following POST request, together with authentication data. If you get a 200 OK from the server it already means you correctly used the CSRF token, and this is an awesome start :)
In order to troubleshoot whether the user has actually logged in or not, that is whether it's credentials were accepted, you can print out the payload of the HTTP response you obtained from the server.
I use a function which prints me the response of the server in case I get an error code greater than 400. The code is the following:
public static boolean printHTTPErrorMsg(HttpURLConnection c) {
boolean error = false;
StringBuilder builder = new StringBuilder();
try {
builder.append(c.getResponseCode());
builder.append("\n");
builder.append(c.getResponseMessage());
System.out.println("RESPONSE CODE FROM SERVER");
System.out.println(builder);
InputStream _is;
if(c.getResponseCode()>=400){
error = true;
_is = c.getErrorStream();
final BufferedReader reader = new BufferedReader(
new InputStreamReader(_is));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return error;
}
You need to tweak it because when you get a 200 OK from the server, there's no ErrorStream but simply an InputStream. So if you change your if condition to =200 and replace the getErrorStream() with getInputStream() you'll see in the log what is actually the content of the response of the server. Typically, if the login failed, the response will contain most likely the HTML code of the login page with the error message saying you provided wrong credentials.
Hope this helps

Unable to get expected response for Facebook photos from an album

I am new to Facebook API. Trying the FQL Query from the Graph API for the first time using this link.
I am trying to get photos from the album with the album id. When I request using Facebook object with https://graph.facebook.com/10150146071791729/photos&access_token=ACCESS_TOKEN URL, I am getting the following response (before parsing to JSON object). {"id":"https://graph.facebook.com/10150146071791729/photos","shares":2}. And I confirmed it by printing the length of the JSON object after parsing, which is 2. When I copy and paste the same URL in the web browser, I am getting the expected response (the response in FQL Query I got). Here is my code.
public void onComplete(Bundle values) {
String token = facebook.getAccessToken();
System.out.println("Token: " + token);
try {
String response = facebook.request("https://graph.facebook.com/10150146071791729/photos&access_token=ACCESS_TOKEN");
System.out.println("response :"+response);
JSONObject obj = Util.parseJson(response);
System.out.println("obj length : " + obj.length());
Iterator iterator = obj.keys();
while(iterator.hasNext()){
String s = (String)iterator.next();
System.out.println(""+s+" : "+obj.getString(s));
}
} catch (Throwable e) {
e.printStackTrace();
}
}
Note: I got access token from the FQL Query which is used in the URL. And I did not wrote any session (login/logout) logic as it is a test project.
Your request is wrong. It should be
"https://graph.facebook.com/10150146071791729/photos?access_token=ACCESS_TOKEN"
Replace the '&' after the photos with a '?'.
Two more things, you're making a Graph API query, not an FQL one.
Second, NEVER post your access tokens publicly. If I wanted to, I can now use your access token to edit your facebook information.
EDIT: When you use the Android Facebook SDK, you do not need to use the full graph path. Instead, use
facebook.request("10150146071791729/photos")
You do not need to add the access token as the Facebook object already has it. Hope this helps.
Because not much code has been provided except for the most relevant one, let me give you a couple of ways you can access Photos from an Album
FIRST METHOD (IF your wish to use the complete URL to make the request)
String URL = "https://graph.facebook.com/" + YOUR_ALBUM_ID
+ "/photos&access_token="
+ Utility.mFacebook.getAccessToken() + "?limit=10";
try {
HttpClient hc = new DefaultHttpClient();
HttpGet get = new HttpGet(URL);
HttpResponse rp = hc.execute(get);
if (rp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String queryPhotos = EntityUtils.toString(rp.getEntity());
Log.e("PHOTOS RESULT", queryPhotos);
}
} catch (Exception e) {
e.printStackTrace();
}
SECOND METHOD (Without using the complete URL as #Vinay Shenoy mentioned earlier)
try {
Bundle paramUserInfo = new Bundle();
paramUserInfo.putString(Facebook.TOKEN, Utility.mFacebook.getAccessToken());
String resultPhotos = Utility.mFacebook.request("YOUR_ALBUM_ID/photos", paramUserInfo, "GET");
Log.e("PHOTOS", resultPhotos);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
On a personal note, I follow the first method almost entirely through my application. It lets me using the Paging for endless ListViews
That being said, when I need some quick data in between somewhere, I do rely on the second method. Both of them work and I hope either (or both) of them helps you.

Twitter:send direct message using scribe

Here is my code to send send direct message using scribe. But it gives me null response. What am I doing wrong?
OAuthRequest req;
OAuthService s;
s = new ServiceBuilder()
.provider(TwitterApi.class)
.apiKey(APIKEY)
.apiSecret(APISECRET)
.callback(CALLBACK)
.build();
req = new OAuthRequest(Verb.POST, "https://api.twitter.com/1/direct_messages/new.format?user_id="+user_id+"&text=my app test");
s.signRequest(MyTwitteraccesToken, req);
Response response = req.send();
if (response.getBody() != null) {
String t=response.getBody();
Log.w("twittersent","twittersent"+t);
}
Can anybody help me ?
Try specifying the format as XML or JSON in your request URL. Also, make sure your entire text file is URL encoded.

How to consume Session dependent WCF services using Ksoap2-Android

I am using Ksoap2-Android for consuming the WCF Services.
For the dotnet client we keep the allowCookies="true" in our binding configuration and it sends the same sessionid and keeps my sessions intact in my WCF services (My services are
interdependent and use the sessions).
Any one know any such setting for ksoap2-android, that will allow me to consume the
WCF service keeping my session intact on the server.
Currently when i make a new call to the service, the sessionid gets changed and all my
session variables clear out and loose their values.
In C# i do the next, just use the android methods to do this:
1.- Make the Http request,
2.- Make a Cookie Container of the first request.
3.- Put the cookieContainer over the second request, for example you can put in a bundle in a intent for the 2nd activity, and use this cookies for send the second http request...
My C# Code;
protected static void GetData()
{
CookieContainer cookies = new CookieContainer();
HttpWebRequest request1 = (HttpWebRequest)WebRequest.Create("https://any.com/url");
request1.CookieContainer = cookies;
HttpWebResponse response1 = (HttpWebResponse)request1.GetResponse();
StreamReader responseReader1 = new StreamReader(response1.GetResponseStream());
Response1 = responseReader1.ReadToEnd();
responseReader1.Close();
responseReader1.Dispose();
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
request.CookieContainer = cookies;
request.Method = "GET";
request1.KeepAlive = true;
try
{
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader responseReader = new StreamReader(response.GetResponseStream());
Response = responseReader.ReadToEnd();
responseReader.Close();
responseReader.Dispose();
if (Response.Contains("Server Error in '/Verification' Application."))
{
Console.WriteLine("Empty Registry" + Url);
}
}
catch (WebException ex)
{
if (ex.Response != null)
{
Console.WriteLine("Failed at: " + Url);
}
if (ex.Status == WebExceptionStatus.ProtocolError)
{
if (((HttpWebResponse)ex.Response).StatusCode == HttpStatusCode.NotFound)
{
Console.WriteLine(ex.Status);
}
}
else if (ex.Status == WebExceptionStatus.NameResolutionFailure)
{
Console.WriteLine(ex.Status);
}
}
}
I do That for keep the sesionID of the first request, and later, in the second request, i add the cookieContainer (because the server requires me) (to make a bot search) ;)... hope this give you ideas.

Categories

Resources