How to prevent some methods - api

I'm developing some APIs with Laravel 5.5
The methods I am using are only 'GET'/'POST'/'PUT'/'PATCH'/'DELETE'.
All works fine except if the request is HEAD or LOCK (for example) ....
In this case, the backend returns a 405 error with an html response. And in this html response there are a lot confidential data.
Is it possible , only for some methods, that the back returns a single text "Method not allowed" and not an html file ? Is it a good practice to do that or not necessary?
I imagine a middleware, but which one?

The reason you're getting debug information with confidential data is likely due to debug being set to true in your config. If you turn this to false, the error message will remove the confidential data.

I found a solution.
File Exceptions/handler.php, method render, I had this:
if ($request->is('api/*') and ! in_array($request->method(), ['get', 'post', 'put', 'delete']) ){
return response()->json("request not allowed", 405);
}
It works fine. Now I receive a JSON response instead of an HTML response for all my API routes, depending on 'get/put/post/delete'.

Related

Bypassing Play's HttpErrorHandler for 4xx errors

I'm writing a microservice in Play. I'd like my controller to be able to generate client errors (4xx) with a particular JSON response body. However, Play's default HttpErrorHandler kicks in, and replaces my response body with an HTML document.
How can I have my response returned to the client untouched?
I have looked into providing a custom HttpErrorHandler, but this doesn't give access to the response that my controller had generated; the signature is:
def onClientError(request: RequestHeader, statusCode: Int, message: String): Future[Result]
Edit: I can no longer reproduce this problem. Now, the error handler doesn't kick in -- which is the behaviour I'd expect. Most likely some form of user confusion / error.
A client error is a condition which is caused by the client, and Play doesn't know how to handle. That includes malformed headers, non-existing resources (read : No route available for that path).
In all cases, this won't hit a controller : It's handled before it's routed. That also means there is no body that can be passed along.
If it does hit a controller, you're free to return a Result with the proper response code and body. If it doesn't hit a controller, and the error handler is invoked, you need to return a response based on the request itself.
An example of what you're trying to achieve would be handy, since it's a bi t unclear to me.

One area of confusion on technical test

I just graduated from a front-end development bootcamp and am experiencing my very first technical test. It all seems very straightforward with the exception of one aspect that I'm hoping to get some opinions on. I'm not quite sure what the company is asking here and was wondering if anyone might be able to interpret it better?
I am to recreate the profile section (name, email, etc.) of a webpage with HTML and CSS, which I understand how to do. There's a JavaScript component involving an HTTP POST request that I'm confused about. There are backend APIs that perform the changing of the profile section.
I was not given the URL for the AJAX call, and was instead provided with the following instructions: "can comment out the actual line that makes AJAX call. Simply assume that you’ll get 200 response with empty string as body. Assume csrf_token to be #####". I've been provided the numbers but have omitted them. Additionally, there was also this line: "the backend API accepts POST request with application/x-www-form-urlencoded body".
In my bootcamp I had not done any POST requests, only GET. Is anyone able to provide some guidance on what exactly this question is asking for? My first step would be to use POSTMAN but without a URL, not sure how to go about this.
EDIT:
From various Googling on how these requests are made, I've so far come up with the below code but still missing a lot (probably). The idea is that if a user were to enter in a new email (or new name, password, etc.), a POST request will be made to make this update.
I've been informed that I'm not allowed to use any jQuery for this test, so I've been trying to learn how to do this in JavaScript alone. Additionally, I'm also not sure where the csrf_token comes in.
var xhr = new XMLHttpRequest();
var url = /* URL */;
var params = ;
xhr.open('POST', url, true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.setRequestHeader('Content-length', params.length);
xhr.setRequestHeader('Connection', 'close');
xhr.onreadystatechange = function () {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText);
}
};
xhr.send(params);
My understanding is that you don't actually have to make the request, only have its place ready in code, maybe commented out. Your code should have a hard-coded 200 OK "response" from the API with an empty body, indicating that changing the profile worked. So that one line that actually makes the request could be replaced with something like a mock object for the request result and you could use that (but the text says the response is empty anyway, so you don't need to mock a lot).
I think your code should still show (in a comment, or in preceding request setup lines before the actual commented out request) how you would make the request, how you would pass the csrf token, how you would set the content-type of the request to application/x-www-form-urlencoded if anything needs to be done (probably not), and how you would pass parameters in that format.

Why can't I make a GET request to flickr api but I the request works when all the parameters are embedded in the string?

I'm trying to make a request to the Flickr api using two methods:
Directly going to
http://www.flickr.com/services/rest/?method=flickr.photos.search&api_key=KEYHERE&text=lol
Going to http://www.requestmaker.com and setting the URL to http://www.flickr.com/services/rest/ and setting appropriate values for headers api_key, text and method.
The second method never works, but the first method does. I'm ensuring the request is a GET request. Any idea why?
I also tried other similar sites for #2 and I'm getting the same error.
I've never used requestmaker until now, but I just tried and it works for me. I'm guessing your input is incorrect - try one of these two methods:
are you using requestmaker GET or POST method (it's the top-right dropdown)?
if GET, then
Request URL: http://www.flickr.com/services/rest/? method=flickr.photos.search&api_key=KEYHERE&text=lol
Request Header: Leave as is
Request Data: N/A (you're using GET so nothing to post)
if POST, then
Request URL: http://www.flickr.com/services/rest/
Request Header: N/A (remove the headers)
Request Data: method=flickr.photos.search&api_key=KEYHERE&text=lol

How to access error response body with AngularJS

my head is spinning cause of the following issue. I'm accessing my webservice (running on my localhost:4434) with AngularJS and if something goes wrong, the webservice sends a response 400 containing a json body which contains a message that tells you what exactly went wrong.
Problem is I cannot access the message on the client? It is almost as if it never reaches the client?? (This isn't the case, I've confirmed that it reaches the client already) This is the angular code that I use on the client site.
$scope.create = function() {
$http.post('http://localhost:4434/scrapetastic/foo', $scope.bar).
success(function(data, status, headers, config) {
console.log("Call to log: "+status);
console.log("Call to log: "+data);
}).
error(function(data, status) {
console.log("Error|Data:"+data);
console.log(status);
});
}
If I submit malformed data a corresponding error response is generated but as I said ... somehow I cannot access the message that is contained in the response body. This is what I get:
I've tried all sorts of things but am seriously stuck now...perhaps someone has an idea on how to access the payload of the response or at least what to do next? I'm also dealing with CORS perhaps it has something to do with that.
Thanks!
I'm going to take a wild guess here and say that your problem is an XSS issue.
Not only do you not have the data variable, but as far as I can tell from your screenshot, status == 0.
Your screenshot also says Origin: http://localhost, which makes this request considered XSS (since the port is different). That would explain why status is 0.
Edit: You can use jsonp to get around the issue.

jQuery POST does not send JSON data

I'm trying to do a POST to a service running on localhost with jQuery AJAX, but it keeps returning status code 0 even after I've set jQuery.support.cors = true. I can also navigate to my WCF REST service successfully from my browser. This is what my JavaScript looks like:
<script>
jQuery.support.cors = true;
$(document).ready(function(){
$.ajax({
type: "POST",
url: "http://localhost:8000/Test",
data: '{"test":"test"}',
contentType: "application/json",
dataType: "json",
success: function (msg) {
alert('success');
},
error:function(x,e){
if(x.status==0){
alert('error 0');
}
}
});
});
</script>
Does anyone know what could be causing this? I should also mention that I can't POST to anything on localhost using jQuery.
According to Fiddler, the JSON data is not sent, and a HTTP OPTIONS is done instead of a POST.
try this
var dataObj = {test:"test"};
var json = JSON.stringify(dataObj);
then in your ajax call
data: json,
I didn't want to spend anymore time on this issue, so I resorted to using raw HTML form POST as the usage of JSON wasn't essential in my case.
For anyone else having the same issues outlined in the original post, see this thread for an explanation and a solution: Problem sending JSON data from JQuery to WCF REST method
To summarize, your service needs to be able to handle the HTTP OPTIONS method if it is expected to respond to cross domain calls.
You should use a tool like network monitor etc. to see if the browser is asking the server for the allowed headers (using the OPTIONS header request), you may need to supply the correct headers in an OPTIONS response before the actual request is sent to the server (see the article at the bottom).
Also, you could try adding this to the actual call or the ajaxSetup, as you will need to tell the browser to send credentials and allow the cross domain call (I know someone else already mentioned 'crossDomain'):
$.ajaxSetup({
crossDomain: true,
xhrFields: {
withCredentials: true
}
});
Have a read of this if you get time too.. https://developer.mozilla.org/en/http_access_control
So, when the request is cross domain, jQuery will send your post request as a get request anyways.
Are you accessing "localhost" in the URL but then your application is sending the requests to the local IP of your machine instead of localhost? Because that's technically cross-domain, which means that you won't receive the request in the expected manner.
E.g. (just tested this locally)
Visiting my local site at:
http://localhost/test/
A form on the site submits to my local ip address instead of localhost via $.post():
<form action="http://10.0.0.17/test/" method="post">
....[form stuff...]
</form>
This is a cross-domain request
If you're calling $.post() or jquery's ajax() call set to post, it automatically moves your parameters from the post body into the query string.
If you ARE accessing local host, try hitting the site via whatever address your jquery post() method is using as the domain and see if that helps.
See more on cross-domain policies:
http://en.wikipedia.org/wiki/Same_origin_policy
Send the data as an Object literal instead of a string
data: '{"test":"test"}',
to
data: {test:"test"},