I am looking for some advice on implementing authentication when the client and the server live in separate projects.
The Server
This API was built as an Express Server. It has routes for CRUD operations with a MySQL database. It also has a user model that utilize bcrypt to encrypt passwords. There is no Frontend, in this project.
The Client
This is a Vue project made with the vue-cli and hits the above API to get the data to display.
The Issue
I need to add authentication. I was thinking I would do this with express-session, but I am a little confused with how exactly it works. All of the tutorials I have seen use express-session in combination with passport. This seems fine, but in all the examples passport forwards to a login page that lives on the server. This is usually written in handlebars or some other templating framework. I am not sure the best way of implementing since the login page lives in the client project.
How I thought it worked (Am I missing something?)
I was originally of the impression that for a new user express-session would create a token that I would save in the users table (maybe generated at login and stored temporarily). Once the user logs in with the correct password this token is passed to the client to be stored as a cookie. When the client wants access to restricted data, it would pass the token as a Authentication header to the server to get permission.
The Questions
Since my projects are separated is passport still useful for my use case?
Is it secure to create the session cookie on the server and send the token to the client as a response to the client's login POST?
Do I need to store the session token in the database?
Is there a better option?
In my project I have almost the same setup, and I ended up with JWT to generate an access token.
The cycle begins with the user sending his/her email and password to my login endpoint.
In this stage I hash the password using some secret string, fetch the user from database and check if authentication succeed.
After that I generate an access token with an expiring time set, and I expected this access token in all protected routes.
With this approach you can easily implements refresh token to exchange at time to time, saving the refresh token in your database.
This is very simple and Is good to you understand how the process of authentication is done.
jsonwebtoken
Related
I see that in most of the keycloak tutorials it is suggested to create two client in keycloak i.e. frontend, backend. But I don't understand the need for this since I can validated the JWT token provided by frontend using public key even without creating separate client.
So my question is, is the approach of not creating the backend app the wrong approach? Also when & why should we create a backend client in keycloak.
Ref - https://medium.com/devops-dudes/secure-front-end-react-js-and-back-end-node-js-express-rest-api-with-keycloak-daf159f0a94e
I see most of the tutorial of keycloak suggest to create two client in
keycloak i.e. frontend, backend. But I don't understand the need of
this as I can validated JWT token provided by frontend using public
key even without creating separate client.
Typically, such tutorials are created to showcase the authentication and authorization capabilities of Keycloak.
The authentication part is showcased by the user authenticating via the browser (using the frontend client), whereas the authorization part is showcased by the application sending an access token to the Keycloak server where the claims on the access token (e.g., roles) can then be used to infer if the user has the permissions to perform the desire action (i.e., authorization).
So my question is, is approach of not creating backend app is not
right approach?
Depends on your specific use case. Alternatively to the approach that I have previously mentioned, one could have had a single client (i.e, the frontend client), and after the user has successfully authenticated, the application would pass the access token to the backend. The backend could then perform the authorization by directly checking, for instance, the roles in the access token, instead of relying on the Keycloak server to do so. There are pros and cons to both approaches.
Also when & why should we create backend client in keycloak.
A typical example would be if the backend would be a separated micro-service that triggers some maintenance task for example. Assuming that task is not related at all to the user authentication process, it would make more sense to then have a separate client (in this case a confidential one) that would rely on the client credentials flow which is typically used for machine-to-machine use-cases.
I'm feeling really stupid right now - I'm an experienced javascript & PHP developer but I just can't get my head round this one!
I have developed a system that allows users to create widgets and embed them on their own sites by including one dynamically-generated javascript file. I have now incorporated an authentication system so users of these widgets can register and login on my client's sites. The registration details are stored on my server.
When a user registers or logs in, I was planning on sending back some kind of encrypted token (of their unique ID) so that when they next access a widget on the same site the code will automatically log them in by sending the token to my server and decrypting it.
However, if this token is stored in the browser via localStorage or a cookie, it will be copy-and-paste-able to anyone that can get their hands on it, resulting in them being able to log in as that user. Is there any way I can achieve what I want without this risk?
Thanks in advance!
You can use JWT. Server generates JWT to frontend and when frontend receives JWT it will store it to localstorage. Localstorage is safe place to keep JWT as long as you make sure that user can't perform any XSS on your application.
You can also solve CSRF with JWT if you send it in HTTP header. That makes sure that unauthorized requests won't go through on other domains. You should check this PHP JWT library out. I have used it on my own projects.
PHP-JWT
I decided to send back a hashed token made up of the user's (encoded) id, password, and salt. I store their encoded id and token, then send both details to the server when automatically authenticating. Should the user's account be compromised through use of this token, they can change their password to invalidate it.
I have an API that is also hosting an OpenIdDict token endpoint. The API does not have any web pages with login forms but instead returns an access token in a response as a result of receiving a form post.
I previously had an old AngularJS frontend which talked to the API to get the token and stored those on the client. Angular was responsible for adding the token to every request to the server.
I am now planning on rebuilding the frontend using Blazor Server. I want the new Blazor Server client/frontend to use introspection against the APIs token endpoint.
My plan was to build a custom Login page that on post would, server-side, talk to the API and get an access token, refresh token, etc. But I have no idea where to put the access token afterwards so that it's used by Blazor through introspection whenever I use the Authorize attribute. I could just return the tokens and maybe write some javascript that saves it somewhere and adds it to any subsequent http requests, but that does not feel like a Blazor Server solution?
My latest discovery is that the tokens could be stored "in session" on the server and a "session identifier" cookie is created on the client? Might be completely off here...
When I played around with the Identity support in Blazor Server a cookie with the name ".AspNetCore.Identity.Application" was always created after a successful login.
Another less desirable solution, or workaround, I have been thinking about is copying the API's OpenIdDict-setup code over to the Blazor Server project and point them to the same database.
Any help here would be greatly appreciated!
My plan was to build a custom Login page that on post would, server-side, talk to the API and get an access token, refresh token, etc. But I have no idea where to put the access token afterwards so that it's used by Blazor through introspection whenever I use the Authorize attribute. I could just return the tokens and maybe write some javascript that saves it somewhere and adds it to any subsequent http requests, but that does not feel like a Blazor Server solution?
You can store the Access Token in the local storage, and retrieve its value whenever you want to use it. Yes, it is Blazor Server solution. That is how you should do it.
When I played around with the Identity support in Blazor Server a cookie with the name ".AspNetCore.Identity.Application" was always created after a successful login.
This is true. Is this a statement or you're asking a question here ?
Anyhow, I guess this cookie will be automatically removed when its life time ends. But in your case, you'll have to do it manually; you'll have to write code that checks whether the access token has expired. If you do not do so, your app will have issues when you try to access a Wep Api endpoint. There is also the authorization components and objects in Blazor that will wrongly perform if you do not manage the stored access token, as for instance, the AuthorizeView embedded in the LoginDisplay component will show the name of an authenticated user (because the claims you extract from the access token constitutes the data from which the AuthenticationSateProvider creates the AuthenticationState object), but no checking of the validity of the access token is perform. But
accessing your web api with the current access token will result in an exception as the access token is not valid.
I've described above something that should be explained by text of hundreds of pages. Hope you're not much confused.
Here's the best place for you to start your investigation Customizing the AuthenticationStateProvider in Blazor Server App with Jwt Token Authentication
Hope this helps...
The Setup
We’re building a PWA (progressive web app). The main components are the app shell (SPA) and the API. The REST API will supply the data needed for the app, while the SPA will handle the rest (as per Google recommendation).
The Problem
Authentication of the end-user seems problematic because the web browser needs to be accounted for. We want the user login to persist through closing down the browser.
We’ve done the research about the possible ways of going about it, however we’d like to ensure that we’re not going in the wrong direction.
Solutions we’ve considered
Session based authentication - the user sends username and password to /accounts/auth and receives a HTTP only cookie with the session ID. The session needs to be stored in a database or Redis. The issue with this option is that cookies are automatically sent by the browser therefore we need a CSRF protection in place. Using the Synchronizer Token Pattern a new token would be generated every time a state changing request has been made e.g. POST. This means that the application needs to supply a CSRF token with every request so that the PWA can send it via AJAX. We determined that it’s not ideal as the user can send multiple post requests in a quick succession making some of them fail and resulting in a bad user experience.
We could also use this method without the CSRF by limiting the CORS policy to same domain and adding a header requirement which technically should stop all CSRF, however we're unsure how secure it would be.
JWT token based authentication - the user sends username and password to /accounts/auth and a new JWT token is issued. The JWT then needs to be stored in localstorage or a cookie. Using localstorage means that JWT is XSS vulnerable and if the token is stolen, an attacker can impersonate the user completely. Using cookies we will still have a CSRF issue to resolve. We considered a double submit cookie method but the CSRF would only refresh every time the JWT is reissued which creates a window for the attacker to find out what the CSRF is. It is not clear which method is best to use.
Session based authentication + JWT token authentication - the user sends username and password to /accounts/auth, a session is created, a HTTP only cookie is set in the browser and a JWT token is sent back to the user. The PWA can authenticate requests with the JWT and whenever the JWT expires the app calls /accounts/auth again to acquire a new one. The /accounts/auth endpoint would still need to be CSRF protected, however the impact of it on usability would be minimised.
There seems to be a large amount of articles claiming that localStorage is insecure and shouldn't be used so why are high profile organisations like Amazon still recommending it? https://github.com/aws/amazon-cognito-auth-js - this SDK uses localStorage to store the token.
You don't need to generate new CSRF token each time a client make a request. It's much easier to use a scheme like token = hash(id + secret + current_day). You only need to update it once a day, or even employ mixed scheme (if the token is invalid today, but is okay for the previous day, the server accepts the operation and returns new token in a predefined header for client to renew it). You may also use the cookie as an id, making the token totally stateless and much easier to check, no need to store them in the database.
Here is how I look at it.
JWT token authentication : with this approach, you can always use a time-bound token with its expiration set to say 2 hours or something?
Or another approach would also be to try and see how you could use some of the approaches the Credentials Management API suggests for example, auto-sign-in of users whenever they come back.
Stuff like 2-step verification with OTPs for instance; for very important features in your web app can be a choice. In this case basic stuff are tied to whichever one time authentication method you have.
Actually, you can also use user-defined pins or short codes (seen a lot in banking apps) to grant access to some features in your web app.
Hope this helps, or sparks some ideation.
I started new project. It is small application (playground) to learn couple new concepts. I will create backend API using Ruby on Rails and Single Page Application using React. I stuck in Authentication. I would like to create custom Token-based Authorization/Authorization. I came to following auth flow:
User fill password/login and send to backed using Ajax and through secured HTTPS connection.
Backed checks if user exist in DB. If user exist backend create Token and save to Redis with user id.
Backend response with token to client app.
On client side I will save above token to local storage.
Before every request I will get token from locale storage and pass to request header.
On backend I will take token from header and check if exist in Redis db.
Is this flow correct? Should I decrypt token on client side or It is not necessary? This project is only playground but I would like to do It properly. Please give me some comments if above flow isn't good enough.
I think that you have the right approach. This link could give you more details about token-based authentication:
Implementing authentication with tokens for RESTful applications - https://templth.wordpress.com/2015/01/05/implementing-authentication-with-tokens-for-restful-applications/
Hope it helps you,
Thierry