How to design RESTful API without using verbs? - rest

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)

Related

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 retrieve user information after login with RESTful services

What should be the standard approach for getting user information after login ?
POST request to validate user/password and retrieve information on response
POST request to validate user/password followed by GET request to retrieve information?
As far as I understand, GET should be the preferred one to retrieve data, but it seems burdensome to performe two requests; at the same time, it feels weird to get data back on POST response. Which should be preferred?
My 2 cents:) if you really want to follow REST Paradigm then you should use standard http method as GET. Although an overloaded POST might do the job however it’s not following the standard.
In SOAP world everything is POST and you can do a lot of funky stuff however in REST world there is a standard on what method used for what purpose ideally.

REST : Correct HTTP verb to check a password

I read many posts about passing sensible data in a GET request but didn't find an answer that would suit my needs.
I have to expose a RESTful resource that will check the password strength.
GET http://api.domain.com/security/password/P#55w0rd
I find the GET HTTP verb suitable since I only want if the password is secure enough.
The problem is that the client will be forced to pass it in the resource (i.e. URL).
Some colleagues told me to use POST and then pass it in the data body but I'm not sure how RESTful is it.
The REST standard just says to use HTTP Verbs. It doesn't actually mandate that you use particular ones. However some conventions have arisen about which verb to use, POST to create & GET to retrieve data, however this should not be followed religiously if it will cause an issue.
As per the following article you should not use GET for password, and yes you can use POST or pass something in the HTTP headers instead.
REST Security Cheat Sheet
Session management
RESTful web services should use session-based authentication, either by establishing a session token via a POST or by using an API key as a POST body argument or as a cookie. Usernames, passwords, session tokens, and API keys should not appear in the URL, as this can be captured in web server logs, which makes them intrinsically valuable.
I went with this:
GET /api/public/check-password
Authorization: Basic <base64(test:<password>)>
The username must literally be either '' (empty string) or 'test'.
I chose to use
test because it's obviously not a real user
GET because no modifications are made
The Authorization header because the security middleware in (most?) application stacks already removes that from logging - so no special care is needed.
/api/public because it doesn't require authentication to do the check
I'm not in love with check-password - that sounds more RPC-ish than REST-ish... but what can you do? At least it's obvious. I'm open to other suggestions.

GET vs POST in REST Web Service

I'm in the process of developing a REST service that allows a user to claim their listing based on a couple of pieces of information that appear on their invoice (invoice number and billing zip).
I've read countless articles and Stack Overflow questions about when to use GET and when to use POST. Overall, the common consensus is that GET should be used for idempotent operations and POST should be used for operations that create something on the server side. However, this article:
http://blog.teamtreehouse.com/the-definitive-guide-to-get-vs-post
has caused me to question using GET for this particular scenario, simply because of the fact that I'm using these 2 pieces of information as a mechanism to validate the identity of the user. I'm not updating anything on the server using this particular method call, but I also don't necessarily want to expose the information in the URL.
This is an internal web service and only the front-end that calls the service is publicly exposed, so I don't have to worry about the URL showing up in a user's browser history. My only concern would be the unlikely event that someone gain server log access, in which case, I'd have bigger problems.
I'm leaning toward POST for security reasons; however, GET feels like the correct method due to the fact that the request is idempotent. What is the recommended method in this case?
Independently of POST vs GET, I would recommend NOT basing your security as something as simple as a zip code and an invoice number. I would bet on the fact that invoice numbers are sequential (or close), and there aren't that many zip codes around - voila, I got full access to your listings.
If you're using another authentication method (typically in HTTP header), then you're good - it doesn't matter if you have an invoice number if the URL, so might as well use GET.
If you're not, then I guess POST isn't as bad as GET in term of exposing confidential content.
There isn't really any added security in a POST vs a GET. Sure, the request isn't in the URL, but it's REST we are talking about here, and the URL wouldn't be seen by a human anyway.
You question starts with some bad presumptions. Firstly, GET is not just for any old idempotent operation, it is for GETting resources from the server; it just happens that doing so should be side effect free. Secondly, the URL is not the only way for a GET request to send data to the server, you can use a payload with a GET request (at least as far as HTTP is concerned, some implementations are bad and don't support this or make it hard). Third, as pointed out, you have chosen some terrible data fields to secure your access. Finally, you are using a plain text protocol any way, so what neither method really offers and better security.
You should use the the verb that best describes what you are doing, you are getting some information from the server, so use GET. Use some proper security, such as basic HTTPS encryption. If you want to avoid these fields 'clogging' up the URL, you can send data in the payload of the request, something like:
GET /listings HTTP/1.1
Content-Type = application/json
{ "zip" : "IN0N0USZ1PC0D35",
"invoice" : "54859081145" }

Why is form based authentication NOT considered RESTful?

Although I "think" I understand it I need some clarity. With PURE Restful authentication, things do get a bit unwieldy and using forms helps a lot with the UI of the application (i.e., get to have separate login page, forgot password links, easier logout? etc.,)
Now Forms come along and some folks say "not restful" - what is "not restful" about them? Is it that there is no corresponding login resource so to speak? Or does it force something else that I'm missing?
Note: If ones create sessions with them, that's a different matter altogether. I'm more keen on know "why" are they branded as restful? Just googling for "Form based authentication vs restful authentication" throws up quite a few hits.
One could use these "forms" to authenticate and pass on tokens for the application to store in cookies etc., which I feel is entirely restful (assuming cryptographic security etc.,)...
There is nothing wrong with sending your credentials, perhaps through a form, for authentication. The problem is most Form based systems rely on sessions, thus requiring you to only log in "once".
Sessions are server state, thus violating the stateless constraint of a REST architecture.
If you have to send the credentials each time, you can either include them in the payload (i.e. using a form), or you can use the HTTP Authorization header.
If you include them in the payload, you can include them in the body, but only for a POST or PUT, and not a GET or DELETE (since they don't have bodies).
If you include them in the URL as part of the query parameters, then the URL is no longer necessarily representing the actual resource. One of the other tenets is that the URL matches the resource. Adding out of band information (such as credentials) within the query parameters muddies that constraint up a bit.
So, for a REST system over HTTP, you're better to use the existing HTTP Authorization mechanism than working out something else. You could also use client specific SSL certs as well, that works fine also.
Excellent question. I think that RESTful purists will likely say that having a URI associated with an action rather than a resource is what makes form-based auth not RESTful, which is something you pointed out yourself.
Honestly I think that the idea of a 100% pure RESTful application is somewhat of a Utopian ideal when it comes to web applications. I believe it is achievable, however, for RESTful web services, since the calling applications can pass credentials with the request header.
At the end of the day, I think that as long as your application works it is fine, and you should not worry about whether or not it is purely RESTful.
That's my $0.02.
From this answer:
To be RESTful, each HTTP request should carry enough information by itself for its recipient to process it to be in complete harmony with the stateless nature of HTTP.
It's not that form-based auth is not RESTful — it's not RESTful to have a session at all. The RESTful way is to send credentials with every request. This could easily be eavesdropped upon, however, but HTTPS/SSL/TLS closes that hole.
Form-based authentication does not use the authentication techniques that are built into HTTP (e.g. basic authentication, digest authentication).
REST purists will ask you to use the functionality built into HTTP wherever possible. Even though form-based authentication is extremely common, it is not a part of the official protocol. So the REST purist sees form-based authentication as an instance of "building functionality on top of HTTP when that functionality already exists within HTTP itself."
Now Forms come along and some folks say "not restful" - what is "not restful" about them?
The authentication credentials are not in the standard place.
REST doesn’t eliminate the need for a clue. What REST does is concentrate that need for prior knowledge into readily standardizable forms. -- Fielding, 2008
RFC 7235 describes the Authorization header; that gives us a standard way to distinguish authorized requests (which have the header) from anonymous requests (which don't have the header).
Because we can distinguish authorized and anonymous requests, general purpose components can do interesting things.
For example, if the origin server is restricting access to a resource, we probably don't want a shared cache to be re-using copies of the HTTP response to satisfy other requests. Because the authorization has a standardized form, we can define caching semantics that restrict what a shared cache is allowed to do.
Putting the same information into a cookie header, in effect, hides the authorization semantics from general purpose components.
(This is somewhat analogous to using POST requests for safe requests -- general purpose components can't distinguish semantically safe POST requests from semantically unsafe POST requests, and therefore can't do anything intelligently take advantage of the safe handling).
If we had smarter form processing -- form input controls that copied information into the Authorization header instead of the query string/request-body -- then forms would be fine. But (a) we don't have that and (b) we are unlikely to get it, because backwards compatibility.