Angular $http.delete request with body - ajax

So I looked at this post:
is an entity body allowed for an http delete request
Which seems to indicate that while it is 'ok' to do on some conceptual level, in practice it may not be doable because browsers just ignore it.
I have some express.js authentication middleware I need to get through, and I don't want to attach my user details to url params. All my other requests that need to authenticate attach these details to the body of the request.
Is there some way to force this? I saw some other posts where some people seemed to have success in passing a body with their delete request.
I am running a node/sails back-end. It always logs the body as undefined for a delete request. Is there any way to modify

The sails API pulls the id of the object to delete from the params, so we have to append the id to the url.
But if I want to pass some authentication details in a body for server-side verification before processing the delete request, I can't just stick them in an object as the second parameter of the delete request, like you can with $http.post.
Angular's post method automatically assigns whatever we insert as a second parameter to the body of the request, but the delete method does not.
Angular's $http.delete method does allow us to supply a config object as the second parameter, through which we can get access to the 'data' property. This is the same way post does it through it's second parameter.
So if we need to attach a body to a delete request we can use the following:
$http.delete('/api/' + objectToDelete.id, {data: {id: currentUser().id, level: currentUser().level}});
This will pass the object to delete's id in the url parameter, and my user credentials in the body as an object.

Honestly, everytime a trouble sounds like a "restriction of as REST", a rethink of the strategy and the philosophy might be a good idea.
I have some authentication middleware I need to get through
I don't want to attach my user details to url params
I'm not directly answering the question, but you should know that among the commons
URL parameters (or query, but URL anyway)
Body
there is a third option for "passing values to the server" :
request Headers
I'd just suggest to consider that third option to provide your credentials: request header.
Edit : following appendix would just apply to any "external" middleware, like a proxy server or whatever, not a true express middleware inside sails.js
In addition, that would be a good idea that your middleware stripped those headers before redirecting to the real action.

Related

How to send a post from twillio webhook using the body instead the params in the request?

There is a way to config the Twilio webhooks in the conversation product to send a post request to an endpoint and in the body send the information instead in the params?
You would pass a payload of the JSON you want to send in your post body and then pass in a header called x-www-form-urlencoded which tells Twilio that you want the parameters to be sent in the body as form data. I'm not sure if it's limited to only a few parameters or not but I know that it works with \"To\" and \"From\" (as they need to be URL encoded). It would definitely work with MessageSid.
You could also use the \"Bulk\" post body format, which is just JSON. This would allow you to pass more parameters since it's just JSON. (You don't need to url encode them if you do this, so no need to have x-www-form-urlencoded header.)
{
\"To\": \"+15551235555\",
\"From\": \"+15551234567\",
\"Body\": \"A text message\",
...: ...
}
You should be able to send the information you want, along with the headers, from your endpoint and have it pass through Twilio.
Looks like this:
curl -X POST https://api.twilio.com/2010-04-01/Accounts/{AccountSid}/Messages -d 'From=%2B15551234567&To=%2B15551235555&Body=Test' -u '{AccountSid}:{AuthToken}'
You can pass any JSON you want as a body using this option but make sure you've set your \"Content-Type\" header to \"application/x-www-form-urlencoded\". This is pretty straightforward and makes it easy to pass in whatever parameters you want.
This isn't limited to text messages! This is exactly how I push data back into a Conversation or Action resource too so it'll work for things like card pushes too! You can use this to programmatically create a response that Twilio will process and then act on in your Conversation or Action instance.
And yeah … if you're going to support a webhook that takes form data then I would suggest adding some basic security checks since anyone could just post random stuff as form data if they wanted and get access to your endpoint. I'd recommend checking the Request Method as well to make sure it's POST.
If you're worried about someone passing in a bad value then you can just check the request body against some regex. I'd recommend checking the Twilio-To and Twilio-From params as well. You could also use the request header too, which is passed along with all webhooks:
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: xxx');

HTTP Requests in Laravel

In Laravel we use routes to deal with HTTP requests from the browser.
We can route a request to a controller, do some logic and then return a response.
Now, we can send in variables encapsulated with braces {} and the response can be anything, so it seems to me that routing through a controller means that the the properties of the different request methods (POST, GET, PUT etc.) are lost.
For example I could send a POST request with URI example/{id} then put in my routes.php file
Route::post('example/{id}','SomeController#SomeAction');
Then I could do something in my controller with the variable $id and send a response.
On the other hand I could send a GET request with URI example/{id} and alter my route to
Route::get('example/{id}','SomeController#SomeAction');
The controller would give the same response.
So, am I right in thinking it does not really matter what request method is used?
Two parts of your question I can identify on a second read-through:
Request methods are not lost. You have access to them with $request->getMethod(). So a GET request will return GET. You also have the method isMethod('GET') available to you, which you could use to get a truthy value which would enable you to return a different kind of response depending on the request type.
With regards to the way you set up your URL, what HTTP verb you use does matter if you're creating a REST-ful web service.
I won't explain away what a REST-ful web service is (you can look it up), here is a couple of points from your example:
If you're getting some data, you ought to be doing a GET request. It is the verb to represent a read from a resource. If you had to send a lot of data - and your intention is to add data, you ought to POST it instead.
The URI should be meaningful in a way that best describes the resource you are manipulating.
Together with the HTTP verb, you can infer the implied action. So if you are POSTing to example/1, I might infer that (and this is a digression, actually) that you are attempting to update record 1 from an example resource. In reality, you would perhaps use the PUT verb (which handles update).
Behind the scenes, Laravel uses a POST request due to browser limitations but treats it as a PUT request server-side.
Of course request type does matter. When you want to hide some request data against user and dont show it in url for example:
?username="Admin"&nick="admin1" then u will use POST otherwise you can use GET. When you want get some data u will use GET but when you want to send some data then you should use POST instead.

Passing session keys in a request body instead of cookies

What's the best way to accept session tokens in the request body instead of as a cookie? I basically want the functionality of ring.middleware.session but without using cookies because it's an API that will be called from another domain.
Are there existing examples/libraries/cemerick.friend workflows that do this?
Would it be too much of a hack to put a middleware function before ring.middleware.session and after something like compojure.handler.api which copies the parameter into the session cookie. You could also wrap ring.middleware.session with your own function which puts the token where middleware.session expects it.

Values in the url is get or post?

I just wanted to know the values which I pass in URL are of Get type or Post type.
Neither or both. They are just part of the query string. Since they are part of the URI, they can appear in any kind of HTTP request.
(Some confusion might occur because PHP will populate the $_GET superglobal with them no matter what verb (GET, POST, PUT, etc) was used to make the request. Some other environments are more sensible, Perl tends to call them Query Params, ASP.NET uses Request.QueryString)
The browser sends any request that contains query parameters, those query parameters populate $_GET. As #Quentin says, they need not necessarily be from a GET request.
On the other hand,
A POST is made most commonly during form submission. $_POST variables are not a part of the URL, and are sent as POSTDATA.

RESTful URLs: "Impractical" Requests, and Requiring One of Two Request Parameters

I have a RESTful URL that requires either the offset or the prefix request parameter (but not both).
GET /users?offset=0&count=20
GET /users?prefix=J&count=20
What's the best way to enforce this rule? Spring has the #RequestParam annotation with the 'required' property for optional parameters, but I want to enforce an "either-or" rule on these two parameters. I know I could do it in the code, but is there another way to do it?
Also, what's the proper way to handle "impractical" requests? Say I have 100 million users; the following request, although properly RESTful, is not something I want to support:
GET /users <-- Gets all 100 million users, crashes server and browser!
What should I send back?
You can create two methods and choose one of them with #RequestMapping's params attribute:
#RequestMapping(..., params = {"prefix", "!offset"})
public String usersWithPrefix(#RequestParam("prefix") ...) { ... }
#RequestMapping(..., params = {"offset", "!prefix"})
public String usersWithOffset(#RequestParam("offset") ...) { ... }
what's the proper way to handle "impractical" requests?
The lesser-practiced principles of REST include the requirement that resources be "discoverable". If you are asked for a complete list of 800 million users and you don't want to provide it, you might instead consider serving a page that describes in some way how to filter the collection: for example, an XForms document or HTML containing a FORM element with fields for offset/prefix/count, or a URI template with the appropriate parameters
Or you could just send a "413 Entity too large" error - edit: no you can't. Sorry, I misread the description of whath this code is for
If you decide to go down the route of just sending the first page, I think I would send it as an HTTP redirect to /users?offset=0&count=20 so that the client has a better idea they've not got the full collection (and if your response contains a link to access subsequent pages, even better)

Resources