REST services - testing PUT methods in the browser - web-services

I've developed REST services. I can test the GET methods by the browser, or by a Client Application. But those who have PUT methods I don't know how to consume them by the browser...
For example, I have this method that turns a lamp on, after I insert the userId:
#PUT
#Path("/lampon")
#Produces({"application/json", "text/plain"})
#Consumes("multipart/form-data")
public boolean turnOnLamp(#FormParam("userId") String userId) throws Exception
{
boolean response = new LampManager().turnOnLamp(userId);
return response;
}
In my client application I do this, and it works:
String webPage = "http://localhost:8080/BliveServices/webresources/services.actuators/lampon";
URL urlToRequest = new URL(webPage);
//Authentication
urlConnection = (HttpURLConnection) urlToRequest.openConnection();
urlConnection.setReadTimeout(10000);
urlConnection.setConnectTimeout(15000);
urlConnection.setRequestMethod("PUT");
urlConnection.setRequestProperty("Authorization", basicAuth);
urlConnection.setRequestProperty("Content-type", "multipart/form-data");
urlConnection.setRequestProperty("Accept", "application/json");
urlConnection.setDoOutput(true);
urlConnection.setDoInput(true);
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("userId", "2"));
(...)
But how can I send the userId by the browser?
Another thing, I get this message when I build my project:
SEVERE: Resource methods utilizing #FormParam and consuming "multipart/form-data" are no longer supported. See #FormDataParam.
Thanks

If you want to test the REST-Webservice with your Browser you must install an plugin.
If you use Google Chrome you can install REST Console I also use these plugin to test my Webservice.
https://chrome.google.com/webstore/detail/rest-console/cokgbflfommojglbmbpenpphppikmonn
For Firefox install these REST-Client
https://addons.mozilla.org/en-us/firefox/addon/restclient/
REST CLient is also available for Safari
http://restclient.net/
For Opera you can check out the Simple REST-Client
https://addons.opera.com/en/extensions/details/simple-rest-client/
For your second Question
please try as Consumes value 'application/x-www-form-urlencoded'

To issue a put-request from a browser you could use jQuery's jQuery.ajax(). (http://api.jquery.com/jQuery.ajax/)
For example:
$.ajax({
url: "test-url",
type: "PUT",
data: {userid: 1}
})
Would send a put-request to test-url with the specified data.

Related

Axios Authorization not working - VueJS + Django

I am trying to build an application using VueJS and Django. I am also using Graphene-Django library, as the project utilize GraphQL.
Now, The authentication works fine and i get a JWT Token back.
But when i use the token for other queries that need authentication, i got this error in Vue:
"Error decoding signature"
and the Django Log also returns this:
graphql.error.located_error.GraphQLLocatedError: Error decoding signature
jwt.exceptions.DecodeError: Not enough segments
ValueError: not enough values to unpack (expected 2, got 1)
the bizarre thing is that the same query when executed in Postman just works fine.
As i mentioned in the title is use Axios for my requests, here's an example of a request:
axios({
method: "POST",
headers: { Authorization: "JWT " + localStorage.getItem("token") },
data: {
query: `{
dailyAppoint (today: "${today}") {
id
dateTime
}
}`
}
});
Note: It uses 'JWT' not 'Bearer' because somehow 'Bearer' didn't work for me.
Ok, couple of questions, does you API work without Vue.js from curl. Generate token, check API from curl.
If it does, then check the Headers sent from the request, from Network Inspector, mozilla dev tools/chrome devtools. And update your Post with those RAW Headers.
This particular error arises when your public key is unable to decode the string[token] signed by your private key. Which ultimately means the access token has been tampered with. It could also mean you're sending values like 'unkown'-- JS state initialization error.
Check the RAW headers of the request. It'll help.
Use a request interceptor to set the Authorization header:
axios.interceptors.request.use(config => {
if (localStorage.getItem("token") != null)
config.headers["Authorization"] = "JWT " + localStorage.getItem("token");
return config;
});

Dart BrowserClient POST not including my cookies

I'm doing a BrowserClient POST across domains and don't see my cookies being included.
This the response I'm getting:
When I send another POST request, I don't see the cookies being included:
Going straight to the test page, I can see the cookies being included:
The Dart code I use to make a POST:
var client = new BrowserClient();
client.post(url, body: request, headers:{"Content-Type" : "application/json", "Access-Control-Allow-Credentials":"true"}).then((res) {
if (res.statusCode == 200) {
var response = JSON.decode(res.body);
callback(response);
} else {
print(res.body);
print(res.reasonPhrase);
}
}).whenComplete(() {
client.close();
});
Not sure about the Access-Control-Allow-Credentials header I'm including, with or without it, nothing changes.
Am I missing headers on the server side that needs to be set on the response or is Dartium blocking cross-domain cookies?
More details on Information Security and the reasoning behind setting cookies via the server.
Update: Enhancement request logged: https://code.google.com/p/dart/issues/detail?id=23088
Update: Enhancement implemented, one should now be able to do var client = new BrowserClient()..withCredentials=true; based on
https://github.com/dart-lang/http/commit/9d76e5e3c08e526b12d545517860c092e089a313
For cookies being sent to CORS requests, you need to set withCredentials = true. The browser client in the http package doesn't support this argument. You can use the HttpRequest from dart:html instead.
See How to use dart-protobuf for an example.

having trouble sending facebook notification via ajax call to php

In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.

Grails RESTFUL web service api

I am currently developing a web app which should do restful service calls to existing web service api.
What I have is the base URL and the API names.
Any help on how do I start working on it?
I suppose I need to use httpbuilder for the base url I have, then followed by /api name. But how do I test it on grails if its working?
When I paste the base url on the browser it does return some xml information, so what I need is to do it on grails instead.
XML response when I paste the url through browser
<ns1:createNewUserResponse>
<userId>21</userId>
</ns1:createNewUserResponse>
So I need to be able to get this response through my web-app (grails) instead of pasting it on the browser.
EDIT*
this is a good example I found useful
#Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
import groovyx.net.http.*
import static groovyx.net.http.ContentType.*
import static groovyx.net.http.Method.*
def http = new HTTPBuilder( 'http://ajax.googleapis.com' )
// perform a GET request, expecting JSON response data
http.request( GET, JSON ) {
uri.path = '/ajax/services/search/web'
uri.query = [ v:'1.0', q: 'Calvin and Hobbes' ]
headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
// response handler for a success response code:
response.success = { resp, json ->
println resp.statusLine
// parse the JSON response object:
json.responseData.results.each {
println " ${it.titleNoFormatting} : ${it.visibleUrl}"
}
}
// handler for any failure status code:
response.failure = { resp ->
println "Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}"
}
}
but i do not understand the query part and how do I alter it to my need?
the URL I have contains credential of username and password, the response should return a securityToken which I need to get it out from the results. Any help would be greatly appreciated!
You can start with groovy-wslite, it provides both SOAP and REST webservice clients.
To make a call to a resfull service look at Groovy HttpBuidler - http://groovy.codehaus.org/HTTP+Builder

JavaFX applet communicating with server

I want to write some page with JavaFX applet. I want content on the applet to be dependent on user logged in.
I know I can call web services from JFX, but then what about login and session? Besides I think there might exist some better solutions for such communication than calling from applet a web service sitting on the machine applet comes from.
How can I do it?
You can build a servlet which returns the name of the logged in user.
Then in javafx you can use the class javafx.io.http.HttpRequest to call the servlet and read out the username. (The API also has some examples of how to use the HttpRequest)
The following javafx code prints out the return string of a Servlet:
var response: String;
def myRequest: HttpRequest = HttpRequest {
location: "http://localhost:8080/demo/foo.do";
method: HttpRequest.GET;
onInput: function(is: java.io.InputStream) {
var buff: StringBuffer = new StringBuffer();
var reader: BufferedReader
= new BufferedReader(new InputStreamReader(is));
var data: String;
while ((data = reader.readLine()) != null) {
buff.append(data);
}
response = buff.toString();
reader.close();
println(response);
}
};
myRequest.start();
EDIT: You should also take a look at this article: http://blogs.oracle.com/warren/entry/authenticating_a_javafx_application_using which shows how to access the html document and cookies from within the applet which resides on the document. That should be a very interesting approach for authentication.