How to design a restful url for login? - rest

I did a research on this topic, but I still cannot find any answer.
I'm trying to use oauth2 and jwt to implement a web login function, then I need a rest style api between backend and frontend.
10 years ago, people just use ..../login to deal with it, but Restful api suggest that there is no verb in the url. So some people suggest that we can use ....../accesstoken, then POST username and password to get a token.
However, I think if we consider an accesstoken as resource, when we want to get the accesstoken, we should use GET method, isn't it?
So my question is: What is the best practice when designing a restful style url for login? Or just restful api is unable to achieve that?
Thanks!
===updated===
in spring oauth2, the default url it provide is post grant_type and relative info to the url /oauth/token. But shoud we use GET method to get resource?

I think "/login" should be ok. In the book, REST API Design Rulebook, here is a paragraph said "Like a traditional web application's use of HTML forms, a REST API relies on controller resources to perform application-specific actions that cannot be logically mapped to one of the standard method (CRUD)." which means the application-specific action, login can be seen as a controller resource. Since controllers are executed by POST method, the final resource can be presented as "POST foo.com/api/login".
The example given in the book is a controller resource that allows a client to resend an alert to a user: POST /alerts/245743/resend

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 resources for a login/registration form

I want to create REST login/registration URI in order to make a an existing user login or a new user to register. After a little search I found that most of such forms are designed using the following rules:
GET /login to get the login resource
POST /login to login and get back the user profile resource
GET /register to get the registration resource
POST /register to register and get back the new user profile resource
However, I think that this is not a 100% REST approach as one of the rules of REST is that resources should be nouns and not verbs (except from some special cases like a search api). What's the best solution for such a situation ?
There's no one right answer to this, so I'll attempt to give some ideas on a common ways to solve this.
Login
Login (aka Authentication) itself is typically handled in a non RESTful way, ourside, such as OAuth2. Should there really be a 'login' if HTTP is stateless? Every request should carry all the information to allow a server to authenticate the client. If you do want to really handle login as a RESTful endpoint, you could ask yourself: "What state am I changing? One way to answer this is that maybe you a creating a set of credentials". I'm assuming for now that you are looking for a best practice / common approach to this though, and not a very purist REST approach for this.
Current user information
Getting the current user is often handled via an endpoint such as /current-user or /whoami. Doing a GET request on this could either yield information about the user, or it could immediately redirect to a canonical user endpoint such as /users/1234. Executing a PUT request could again either update the user, or return a redirect to the actual user endpoint.
Registration
If you have a list of users on a resource like /users. It would kind of make sense to create a new user resource by doing a POST request on this collection.

If this Facebook Graph API is restful

Facebook has an API to get your photos:
GET graph.facebook.com
/me/photos
/me/ is a shortcut for the Id of the person logged in. Is that introducing state into the session and therefore is it restful?
Would it not be more restful to do:
/user/1234/photos
and then have some security layer to make sure only users with the appropriate token can access that URL?
https://developers.facebook.com/docs/graph-api/using-graph-api
Noticing some other places use this pattern. For example:
Stripe do this for GET all coupons:
GET https://api.stripe.com/v1/coupons
Paypal do this for all payments:
GET /v1/payments/payment
https://developer.paypal.com/docs/api/payments/
GraphQL is not restful, I tried to sum this up here.
The /me does not necessarily introduce state, because the id for me could be in the headers, so the serverside can still be stateless.
Is that introducing state into the session and therefore is it
restful?
In fact statelessness is a constraint for rest, so you would have to rephrase your question to "... therefore is it not restful"
But REST relies heavily on URIs, so this shortcut circumvents being transparent in the URI, what is not the best idea according to restful principles.
REST IS a concept/approach/way to provide interoperability between computer systems.
REST IS NOT a standard, approved by a committee/organization in terms of strict regulations.
While there are architectural constraints, recommendations, unwritten rules, common solutions, you can't truly affirm this is rest or this is not rest. Everyone design its service as he thinks it's better.
Graph API is not exactly REST, they are a bit just different things/meanings.
Related to FB /me they said:
The /me node is a special endpoint that translates to the user_id of
the person (or the page_id of the Facebook Page) whose access token is
currently being used to make the API calls.
As this URI depends on authenticated user, what's the problem with it?
Related to PayPal, I think You prefer /v1/payments/payment instead of /v1/payments/35/payment, but the same app deployed to another customer will be /v1/payments/69/payment or a logout like /v1/user/35/logout.
It's all about convenience.

Restful principles - sending user's identifier in HTTP headers

I'm creating restful api that is used by angular web page. I'm using token based authentication. Server side determines which user sent request based on token value, so I don't have to pass user id on URI. For example, request that returns all orders for logged (with token) user looks like this:
/api/orders
instead of:
/api/users/123/orders
Api is still stateless, but the same URI returns different data depending on headers. Is it consistent with Restful principles?
I think that this suggested API violates the address-ability feature of REST. The address of a resource should be in a form that is visible and readable (and some other things not related to your question...). One of the nice things of nice URIs is that one can link to it easily. Headers are actually hiding the real address of the resource hence making it impossible to link to it. So bottom line I would not go for such an API.

How to make OAuth API Restful

I refer many document for trying making api Restful like below:
GET /user
POST /user
GET /user/123
PUT /user/123
DELETE /uesr/123
But Backend uses OAuth2 token to retrieve user id, it means that Server will know 123 after get token.
I thought it's not a great idea to put token directly in the id place:
GET /user/aweakleknf11123232sadwanawndajkdnamdal
Is any better practice to the restful OAuth2 API?
While designing RESTful api don't think too much about how your url look, rather it is just representation of your resources.
And moreover it is not good idea to expose domain model of your project if your api is public.
If you have gone through Facebook api design you can see that they refer user as
/me?method=GET&format=json&access_token=...
They have abstracted the domain and just sharing self descriptive representation.