I am creating an 'API as a service' by developing a separate REST API server and a web-app server which simply serves up a website that consumes the REST API. The web-app acts as a client of the API. The web-app is a simple dashboard that allows a user to login and see their API usage and view their API secret and keys so that they can access the API securely.
I am planning on using AWS-like shared secret to enable clients of the API to access protected resources.
But one thing im confused about is when the user logs in to the dashboard website, should this be handled by the REST API, or by the web-app server.
If it is to be handled by a REST API endpoint, how does the API server maintain session state between requests. How does the API know if the user is logged in or not? Is it ok to store session state on the API server, even though it is supposed to be stateless. How do other rest-like API's like twitter do this?
ReSTful security is handled server-side; basically:
the server returns a 401 status code when a client ask for a resource without been authenticated
every client call have to provide authentication through a WWW-Authenticate header
this header can be store client-side in a cookie after a successful login
You will find great help on the matter in the book: ReSTful WebServices Cookbook. Look for explaination on basic / digest authentication.
Here is a good introduction with a live working sample.
Related
Consider that we have:
An SPA or a statically generated JAMStack website.
A REST API.
The website is being served with nignx that also reverse proxies to our API.
--
It is required that a user should be able to register/authenticate with an identity provider (say, Google) through the OpenID Connect protocol. For the sake of simplicity, let us assume that the user has already registered with our API.
Talking about authentication using OIDC, from what I have read on the subject, the steps you take are the following:
Register the application with the IdP and receive a client id and a secret.
When the user initiates a login (with Google) request on the API ('/api/loginWithGoogle') the API sets a state variable on the request session (to prevent CSRF) and redirects the user-agent to the IdP's login page.
At this page, the user enters their credentials and if they are correct, the IdP redirects the user to the callback URL on the API callback (/api/callback).
The request received on the callback has the state parameter (which we should verify with the one we set on the session previously) and a code parameter. We exchange the code for the identity token with the authorization server/IdP (we also receive access/refresh tokens from the auth server, which we discard for now because we do not want to access any APIs on the behalf of the user).
The identity token is parsed to verify user identity against our database (maybe an email).
Assume that the identity is verified.
-- The next part is what's giving me trouble --
The documentation that I have read advises that from here we redirect the user to a URL (e.g. the profile page)and start a login session between the user agent and the API. This is fine for this specific architecture (with both the SPA/static-site being hosted on the same domain).
But how does it scale?
Say I want to move from a session based flow to a JWT based flow (for authenticating to my API).
What if a mobile application comes into the picture? How can it leverage a similar SSO functionality from my API?
NOTE: I have read a little on the PKCE mechanism for SPAs (I assume it works for JAMStack as well) and native mobile apps, but from what I gather, it is an authorization mechanism that assumes that there is no back-end in place. I can not reconcile PKCE in an authentication context when an API is involved.
Usually this is done via the following components. By separating these concerns you can ensure that flows work well for all of your apps and APIs.
BACKEND FOR FRONTEND
This is a utility API to keep tokens for the SPA out of the browser and to supply the client secret to the token service.
WEB HOST
This serves unsecured static content for the SPA. It is possible to use the BFF to do this, though a separated component allows you to serve content via a content delivery network, which some companies prefer.
TOKEN SERVICE
This does the issuing of tokens for your apps and APIs. You could use Google initially, though a more complete solution is to use your own Authorization Server (AS). This is because you will not be able to control the contents of Google access tokens when authorizating in your own APIs.
SPA CLIENT
This interacts with the Backend for Frontend during OAuth and API calls. Cookies are sent from the browser and the backend forwards tokens to APIs.
MOBILE CLIENT
This interacts with the token service and uses tokens to call APIs directly, without using a Backend for Frontend.
BUSINESS APIs
These only ever receive JWT access tokens and do not deal with any cookie concerns. APIs can be hosted in any domain.
SCALING
In order for cookies to work properly, a separate instance of the Backend for Frontend must be deployed for each SPA, where each instance runs on the same parent domain as the SPA's web origin.
UPDATE - AS REQUESTED
The backend for frontend can be either a traditional web backend or an API. In the latter case CORS is used.
See this code example for an API driven approach. Any Authorization Server can be used as the token service. Following the tutorial may help you to see how the components fit together. SPA security is a difficult topic though.
I have a web site written in Angular that uses a REST api in order to provide functionality.
I would like to know the proper workflow for authentication to the website.
Let's go back to 1999 - I write a website and all the logic is in the web code. There is no REST API. If someone wants to log in to the website they enter their email and password and I store a cookie on their machine and they now have a 'logged-in' session on my website. By having this cookie they are authorized to do certain things such as write a comment.
All good.
Fast-forward to my new website. This website is written in Angular and all content is provided via a REST API. Some of the REST calls just display data like a bunch of comments. Any anonymous user can make these calls just by browsing the page. However, there the user can log in to the website using their email and password. Again, I store a cookie on the user's machine and they are logged in to the website. Now, because they are logged in to the website they can post comments. These posts are done via a REST API call. However, Google and the Interweb have told me that my REST API should be stateless and i should be using oauth2 for this request.
My question is, what is the workflow for this very common auth pattern?
I thought maybe something like:
User logs in with username and password
One request is sent to my web auth server and a session cookie is created
A second request is sent to my api auth server which issues a valid token for further requests
The two systems are quite separate and do not depend on each other.
If i was to add social login to the mix then (2) above would just be authentication to the required social auth server and (3) would be unchanged.
Yes, your REST API should be stateless.
This is a typical workflow for authentication for a REST API.
User logs in with username and password.
A JSON web token is issued upon login from the backend and sent to the browser.
The JWT(JSON web token) can be stored in a cookie in the Web Storage(local/Session Storage) on the browser.
Subsequent requests to the REST API will have the token embedded in the header or query string for authorization. With that form of authorization, your REST API understands who is making the request and what kind of resource to return based on the level of authorization
A practical example of this can be found in this blog post. Angular 2 was used for the sample app implementation.
I hope this helps!
My plan is to develop an application which creates user recommendations based on the userĀ“s Facebook data (age, likes,...).
In this Figure (sry, i am not allow to post images directly) you can see the flow of the application. Is this the configuration "Login on Client, API Calls from Server" from the Facebook Documentation?
I am not sure because the Recommendation Server, which calls the Graph API, is not the same as the Web Server. Additionally, in the documentation it is mentioned that the Client forwards the API calls to the server. However, in my case the Web Application (Client + Server) does not know which API calls the Recommendation Server makes.
Is my project feasible? If not, how do I have to adapt my plan?
I don't see a problem here if I understood correctly. Have one web server to the OAuth login, exchange the short-lived Access Token for a long-lived one, and store the Access Token somewhere in a (NoSQL or SQL) database such as Redis, MongoDB or MySQL where both web server and recommendation server have access to.
Then, the web server needs to trigger the recommendation server to do the calls he needs after the Access Token has been stored.
I'm currently tyring to build an API driven symfony2 web applicaiton.Just a basic application to learn symfony2 and REST.
It would be based on a RESTful api. Calls to the API will be authenticated using OAuth.
For e.g.:
if a client application wants to get data (information about all the fruits) through API it will need to make a GET request to the url and pass the access token as a parameter.So the url will look something like this.
http://www.mysite.com/api/fruits.json?=<access token>
Now the problem is that i would be needing the same data in one of my actions as well.
I need some help here.In order to get get data from above url in one of my actions i will also need to send an access token in the url.
How do i get this access token??
Should there be a fixed token which will be used for all such calls within my application??
You basic application project will grow manifold if you try to do what you want here.
Basically, you need to implement an Authentication Server for this.
i) First, the app should be registered for a scope;
ii) Using the app the user logs in to the authentication/authorization server.
iii) The server verifies if the app has access to the scope and if the user is registered in your system.
iv) Server creates an access token (which is a HMAC signed string) and returns to your app.
v) The app then hits the endpoint (restful API) with the token.
vi) The RESTful service then internally sends the token to the server and fetches the customerID for which the call is made and performs the actions that it's supposed to.
I wrote an answer once on how to create a OAuth Service/Provider - How would an efficient OAuth2.0 server / provider work?
Also, OAuth was designed such that client apps/3rd party software can access a user's resources on his behalf. A very simple example is = An app posting something on your facebook wall on your behalf. It is actually accessing a resource that you own (the wall) and posting to it. You do not need OAuth just to get some data - there are other ways to secure the API.
I am creating a solution that will contains a website and mobile apps. I will use Zend-Framework 2 for the website.
So, to make it good, I am wondering if it would be a good idea to build :
A REST web service (using zf2)
Another website that will call the REST ws (using zf2)
The mobile apps that will call the REST ws
I will use OAuth for the autentication and security.
My question is, if my website gets the data by calling the REST ws, it will have to make a database request at each call to check the token whereas if I do a "normal" website, my app will be able to use session to store the information of the connected user.
Because, for what I have read, there is no such thing as session with OAuth/REST so for each call, I have one more sql request to check the token validity.
Is it still a good idea to make a full REST service, even for the website or to have a "normal" website and also a REST service API just for the mobile apps ?
Thanks
Oauth is a server to server authentication framework. Like it is between mobile app and your API server , website vs your API server etc. You can adopt an approach where , you generate only one access token for your website client instead of multiple access token for each user from the website. This access token is stored in your webserver vs user cookie in website.Ultimately the aim is to identify all the clients of your REST WS and your website is one of its client and a very trusted one.
This way you can cache the access token to avoid db calls (typically cache time can be equal to or less than token expiry time). Do explore the multiple grant types specified in the oauth spec for this
Regarding maintaining session for user in your website, it is not dependent on whether the back end is a REST WS or not, it can be handled in your website