2

I am fairly new to web development, and I am learning to build web applications. I am facing a problem figuring out how to set up authentication mechanisms for a multi-user application. Let me provide some details about the architecture: Architecture

Here I have two web servers - Front-end application (written in Angular) and a back-end REST API. The two exist separately to have a more decoupled system (back-end provides the data, front-end presents it), as well as to allow third-parties to implement their own client-side applications. I am not sure if it is relevant, but the back-end API is a PostgREST web-server sitting on top of a PostgreSQL database.

As I mention before, this is a multi-user application, so I would also like to set up authentication for clients. In the context of my architecture it means setting up authentication for www.domain.com to api.domain.com as well as for client to www.domain.com. I think that it makes more sense to use token-based authentication to access the back-end API, as it will not be accessed by browser-based client directly. As for the authentication on www.domain.com I think I have options to either go for token-based or session-based authentication. If am getting it right the authentication process should look something like this: enter image description here

The problem is that I do not understand how to set up the translation of client-www.domain.com authentication to the one between www.domain.com and api.domain.com. What kind of authentication mechanism is most suitable for the browser-frontend communication in this situation? How to "forward" the authentication to the back-end API? Is there another way of achieving this?

  • I'm wondering what was the reason for the downvote. Seems that the question is clear and on-topic, and the OP made an effort researching the subject. – Arseni Mourzenko Jul 20 at 19:57
0

The situation is quite common. The clients of the API are not the actual people using an application, but rather the applications between the final user and the API—your web application, or an Android/iOS application, or a batch script. All those API clients, however, can access users' data, which creates the problem: the API is not expected to give unlimited read-write access to users' data to any client willing to access it.

Why not? For two reasons:

  • If the API is public, i.e. anyone can write a client, you're giving access to users' data to everyone. This is not acceptable in nearly every case.

  • If the API is not public, i.e. you are the only one to be able to add clients, then you'll quickly find yourself limited in terms of which client can be created. Web application would be OK, as it's hosted on your servers; everything else is not. This means that it will be impossible, for instance, to have client apps for mobile devices or even applications for desktop PCs, since the exchange between such client and your server can easily be decrypted, analyzed and tampered with (HTTPS won't help at all here, since the owner of the device would be able to generate a custom root certificate).

This means that it belongs to the user to confirm that he authorizes a given application to access his data through the API. You can see this sort of interactions a lot if you use applications which need to access your Google Drive or your Facebook data: Google and Facebook respectively will ask you to confirm that you want to give access to your data for a given application, explaining what exactly the application will be able to access, and it belongs to you to accept or refuse.

This, however, has one limitation: if the users come to your https://www.example.com/, and are welcomed with a screen from https://api.example.com/ asking whether http://www.example.com/ can access their data or not, they won't understand. This means that you should have a list of trusted clients: in your case, the web application would be a trusted client of the API, being granted unlimited access to the data of every user.

This doesn't mean, however, that you should necessarily POST http://www.example.com/login. This is one way of doing it, but a simpler approach would be to use OpenID or OAuth 2.0. This became a de facto standard way of authenticating users, and if you rely on somebody else, such as Google, to do the authentication, you get a huge benefit of not having to deal with passwords.

  • Thank you for the answer! But I think the approach of the web app being a trusted client of the API does not fit my needs that well. Mostly, due to the fact that I do not want to specifically grant other third-party applications permissions to access the unlimited read-write access. I expect my web app to act pretty much like highly-abstracted curl utility with a very domain-specific graphical web interface. Essentially I do not want regular users to not be able to access the back-end API directly. I want them to even be able to build their own client app. – Big Monday Jul 21 at 15:56
  • It is just that I am not sure I need a different authentication mechanism for the front-end server. Maybe I could just use the same token for the front-end authentication as well as for the back-end. This way the user can navigate the front-end app with their token in the HTTP header, then take this token and use something like postman to query the API directly. – Big Monday Jul 21 at 15:56
  • Naturally. The web app will have a special status with unlimited access; other clients will have an ordinary status, requiring the user to confirm that he authorizes those apps to access user's data. – Arseni Mourzenko Jul 21 at 17:19
0

The architecture you described is pretty common so far, I think you are missing just one thing:

In case that your app and your backend reside on different domains, you can't use cookies any more to store the token. The typical process would be: user posts credentials via app to backend, backend creates a token, app stores the token in localstorage. On every following request from the app to the backend, you append the token to the Authorization-header of your request.

Authentication and authorization happens in the backend. In the response to the login-request, the backend can provide infos to the app such as "user is admin, user has permissons xyz" and so on. Based on that information, your app hides / displays links and functionalities.

Surely a user can manipulate that response and can make himself an admin or something - as a result, the user would see the admin links. But when he uses these links and tries to send requests to these admin-endpoints on the backend, your authorization component in the backend should kick in and rejects the request and respond with a 403.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.