Symfony REST submit Post without form? - forms

Do I need to use a form (formbuilder) to submit POST Data to symfony? For example login by xml or something like that?
I'm confused as there are people telling me I have to, and on the other hand there an some who tell me that I don't need to because I use it as a REST api???
It would be great if we can go through the possibilities I have with REST and CRUD.
I'm a bit confused because in case of a login, I don't want to nind a request to a form or an entity or is this the only way handling eg. login data?
Thanks in advance for your help.

Actually I think it's your own choice. There is no requirements to do things in single way. Do you think you need form - use form, no - no.
I think if action from your REST API doesn't relate to any entity it's absolutely not necessary to use forms. But if the action is aimed to handle CRUD request (POST or PUT) it's more convenient way to use forms. But anyway it's only your choice.
In some cases (in standard and pretty simple cases) it's much easier to use form and I think it's the best and fastest way to make something work. But if you need to customize form it might be too difficult and might take some time to solve all of the issues.

One approach to "login" is to think in terms of access tokens.
POST /tokens with a payload (xml or perhaps json) of user name and password. The server authenticates the user, then generates and returns an unique token linked to the user.
On subsequent REST requests, include the token in the header of the request. From the token, the server can determine the user and access protected resources accordingly.
http://symfony.com/doc/current/cookbook/security/api_key_authentication.html
This of course is only one approach that has worked for me.
===========================
By the way, #Alex of course answered your actual question on forms.

Related

How to design RESTful API without using verbs?

EDIT:
This question has nothing to do with "will the browser work with a non-restful API" or "Token authorization headers". This question has to do with API-Design (look tags), Good practices and Authentication (/login), not Authorization (token header).
I know how to make an API, how HTTP protocol works, what is RPC and what is REST. If you read my question you might see that I understand the principles. Please read my question carefully. Dont just read the title itself and answer. You need context in order to answer.
I'm trying to design a REST API without using verbs. It's becoming more challenging, as I'm comfronting cases like Login/Authentication like controllers.
Like, how am I supposed to treat natural controllers like Authentication in a RESTful Service? I'm probably being too pedantic here, if I am please correct me, but if my API contains a request like
GET /authenticate
then it isn't considered fully restful by definition. Right? I mean, this is clearly a verb. Thus it's a RESTful+RPC API.
And if I break my REST principles for /authenticate then why should I not break my REST principles for other cases that make my life easier? Like some other business controllers for example:
GET /users (noun) REST
POST /register (verb) RPC
GET /logout (verb) RPC
This might seem like a very semantic issue, and if it does I would love you to tell me that I probably think of this in a stupid way, so I can stop caring about this. But it really seems strange to me to consider an API RESTfull when it clearly has verbs in it, so that's why I'm asking your opinion.
Otherwise, if there is a better more RESTful way to perform authentication, I would love some recommendations. As it was troublesome finding answers on the topic on Google, other than people saying "Dont use verbs in RESTful API", which is confusing in cases like this.
Disclaimer: (for not careful reviewers/readers)
This is probably not a duplicate of some other questions you might have seen, like this one
How to create REST URLs without verbs?
I'm aware of what the correct solution is for this specific question, as OP asks something that can be very easily done by REST.
My issue is more semantic and not as much as a question over how to do basic REST operations like updating a user's field.
Neither this that I found is a duplicate but indeed very similar
REST API Login Pattern
The user asks which is an appropriate RESTful design, but he clearly does not get any answers that are answering what I'm asking. Which is the semantic (stupid or not) of "Is the design RESTful anymore if you have a /login path in your RESTful design". The answers are about Authorization, not Authentication.
Im forming this disclaimer because some of my past questions have been downvoted because they were considered duplicate, when they were actually just similar, and the downvotes were never removed even though I never got an answer back.
Although, if you find an appropriate duplicate I would be really happy to accept it. Just please dont rudely throw a duplicate with the only duplicate thing being the title.
An example REST client and server with local login would be:
Server API's:
GET /users/currentUserReturns a JSON document which describes the current user (display name, email address, theme preference, password expiration date, etc...)
Validate username and password in Authorization: basic header, set context. If invalid, throw 401
Retrieve user information, serialize, return
GET /todos/Returns a JSON document which contains all of the TODO items
Validate username and password in Authorization: basic header, set context. If invalid, throw 401
Retrieve To-Do items, serialize, return
Client:
Start in "Unauthenticated" state, display login UI
When login button is clicked, use username and password fields to compose a Authorization: basic header and add it to the HTTP client
Make a test call to GET /users/currentUser with the header to validate login info and retrieve user information. If 401, login failed - return to login UI.
Save the Authorization: basic header and transition to the "Authenticated" state, display app UI
Make a call to GET /todos/, format and display. If a 401 occurs, transition to "Unauthenticated" state (e.g. password changed by other client)

REST API design for resource modification: catch all POST vs multiple endpoints

I'm trying to figure out best or common practices for API design.
My concern is basically this:
PUT /users/:id
In my view this endpoint could by used for a wide array of functions.
I would use it to change the user name or profile, but what about ex, resetting a password?
From a "model" point of view, that could be flag, a property of the user, so it would "work" to send a modification.
But I would expect more something like
POST /users/:id/reset_password
But that means that almost for each modification I could create a different endpoint according to the meaning of the modification, i.e
POST /users/:id/enable
POST /users/:id/birthday
...
or even
GET /user/:id/birthday
compared to simply
GET /users/:id
So basically I don't understand when to stop using a single POST/GET and creating instead different endpoints.
It looks to me as a simple matter of choice, I just want to know if there is some standard way of doing this or some guideline. After reading and looking at example I'm still not really sure.
Disclaimer: In a lot of cases, people ask about REST when what they really want is an HTTP compliant RPC design with pretty URLs. In what follows, I'm answering about REST.
In my view this endpoint could by used for a wide array of functions. I would use it to change the user name or profile, but what about ex, resetting a password?
Sure, why not?
I don't understand when to stop using a single POST/GET and creating instead different endpoints.
A really good starting point is Jim Webber's talk Domain Driven Design for RESTful systems.
First key idea - your resources are not your domain model entities. Your REST API is really a facade in front of your domain model, which supports the illusion that you are just a website.
So your resources are analogous to documents that represent information. The URI identifies the document.
Second key idea - that URI is used by clients to cache representations of the resource, so that we don't need to send requests back to the server all the time. Instead, we have built into HTTP a bunch of standard ways for communicating caching meta data from the server to the client.
Critical to that is the rule for cache invalidation: a successful unsafe request invalidates previously cached representations of the same resource (ie, the same URI).
So the general rule is, if the client is going to do something that will modify a resource they have already cached, then we want the modification request to go to that same URI.
Your REST API is a facade to make your domain model look like a web site. So if we think about how we might build a web site to do the same thing, it can give us insights to how we arrange our resources.
So to borrow your example, we might have a web page representation of the user. If we were going to allow the client to modify that page, then we might think through a bunch of use cases (enable, change birthday, change name, reset password). For each of these supported cases, we would have a link to a task-specific form. Each of those forms would have fields allowing the client to describe the change, and a url in the form action to decide where the form gets submitted.
Since what the client is trying to achieve is to modify the profile page itself, we would have each of those forms submit back to the profile page URI, so that the client would know to invalidate the previously cached representations if the request were successful.
So your resource identifiers might look like:
/users/:id
/users/:id/forms/enable
/users/:id/forms/changeName
/users/:id/forms/changeBirthday
/users/:id/forms/resetPassword
Where each of the forms submits its information to /users/:id.
That does mean, in your implementation, you are probably going to end up with a lot of different requests routed to the same handler, and so you may need to disambiguate them there.

HATEOAS - REST is not truly REST

When REST API don't follow HATEOAS style, it is often referred your REST is not truly REST.
How come we can think of every possible request from clients can map to CRUD operations?
For example if the client(mobile) would like to send a reset password link to user for a given email id, how this shall be thought of as CRUD?
Very few REST advocates will argue that that REST should be applied to everything. I'm a big proponent of REST, but there are more than a few situations where not using HATEOAS is the most pragmatic move. Your example is one of them.
However, if you want to make this work in a RESTful manner, it's totally still possible.
For example, a lost password reset link might require a one-time authentication token. This token might be represented by a resource in a collection such as:
/users/xyz/auth-tokens
And perhaps you can initiate a lost-password email operation by creating a new 'auth-token' resource in that collection using POST.
Should you? I don't know! Can you? for sure!
Creating a PasswordReset resource is easy enough.
POST /password-resets
RPC minded people struggle to switch over to REST because they're used to doing things as RPC. :)
https://www.smashingmagazine.com/2016/09/understanding-rest-and-rpc-for-http-apis/

How to add CSRF token to login form?

I'm not sure whether this is necessary, but I don't see any csrf tokens in the login form. Usually when you create a form, you add form_rest(form) at the end, and that adds the csrf token. But the login form is handled differently, it's not really a form object, it's kind of automagic. You can see that in the docs.
So what's up with that? Why there is no csrf protection for the login form? I know CSRF attacks are for authenticated users, but anonymous users in Sf2 are technically authenticated (see the session cookie), and also I might want to have some kind of gradual engagement, like in stackoverflow, where you can perform some actions without being a confirmed member.
Any thoughts?
CSRF protection is not necessary on login forms.
CSRF definition: an attacker can force a victim to send an HTTP request to a server.
Typical school-book example: to initiate a money transfer.
The attacker can force a request like this: http://bank.example.com/withdraw?account=Alice&amount=1000000&for=Eve
As you see, the attacker must bake a URL beforehand.
In the case of a login request, it does not make sense, because the attacker must bake a URL like this: http://example.com/login?user=pierre.ernst&pwd=secret.
If the attacker has this information (credentials) already, chances are he will not try a CSRF :-)
Hoping it helps.
Actually, form_rest(form) does a lot more than throw in the CSRF token, this function prints out any form rows that have yet to be rendered, and is good to put in to ensure that any additional fields that have been neglected are sure to be rendered.
The reason you're not seeing a CSRF token is because the FOSUserBundle login form is not a Symfony form, it's just a regular HTML form that is then processed by the FOSUser form handler.
I'm not entirely sure why this decision was made but I am sure there was a technical reason behind it, and that if it is a problem you could add one in manually and extend the form handler to process and validate it in the response, I believe the service is parameterised so it should be relatively easy to swap out.
My big question though would be why you would bother doing this? Is it a massive deal? CSRF is a useful step but not the be-all-and-end-all solution for security, and personally, I'd have bigger priorities than this, if it's a big deal it'll get fixed in FOS at some point.
With your latter point, I'm not sure of the relevance, how does this stop you from achieving gradual engagement? A quick tip regardless, whilst I didn't architect this part of the system myself, on an ecommerce project I've been working on recently, the lead decided that to achieve gradual engagement (so people could checkout anonymously) but still persist a lot of their actions, very early on new users are persisted with a autogenerated username and a custom role such as ROLE_GUEST, with the default functionality in Symfony proving insufficient for our use case.

REST and Building Forms that Redirect

I'm build an application along RESTful principles. I have a user-facing form that POSTS to create a new comment, the URL for that action is POST {article}/comment
After the POST happens, I want to redirect the user to GET {article}/thanks
But I'm not sure how to implement this. It seems un-RESTful for the POST {article}/comment resource to also have the logic knowing about the next step for the underlying {article}
Any thoughts? Thanks!
You should consider applying AJAX principles to submit your form, receive a success/fail/other response from the server, and to take further action (redirect) based on that response.
You will find a lot of help using some frameworks like jQuery that will help posing your form and process responses, take a look at this blog post, especially its consume part.