Best way to handle authentication on a react-redux single page appliction? - node.js

I'm currently sending the client an empty html document with a few scripts included that set up my single page application with react-redux. After everything is set up I'm fetching the dynamic data using AJAX and determine if the user is logged in or not. If the user is not logged in, he will see the products available only for users that are not authenticated and conversely.
Even though I am a noob, this seems extremly primitive to me and I don't know how I can do this better.
So what is the best way to handle authentication in react-redux applications?
Thanks a lot for helping.

There's a few options:
Passport which you can install through npm and it has a variety of strategies you can authenticate through such as Auth0 Link here
Firebase - a solution that google has that can be used as a drop-in authentication module. Link here
Meteor framework - I believe this framework has multi user authentication. Link here

First, for authentification you need to have a token or session id on the client side. So, there should be next steps:
After login, you receive token|session_id from backend and put it to the store and also to the localstorage not to lose it after page reload.
While initializing your app, get the token from localstorage and put it to the store every time.
When you do request for products list, add the token to ajax request (usually in headers).
Based on token, back-end application should returns another list of products.
It is a regular logic for such situations and of course it requires work on back-end side as well.

Related

Having one backend manage authentication for a webapp and react native app

Im planning on making an application that has two parts two it:
React native mobile app
Browser web-app for desktop users
I'm trying to plan out how im going to manage the backend authentication for this (Node.js, passport.js). Ideally, I can just have one backend manage it, regardless of which type of client.
Lets say im going to ONLY have google auth (for simplicity). I don't need to hit googles API's for any information (like profile, contacts, etc), I just want them to login with a google account. My understanding so far is that theres two main ways (especially since im using passport.js).
jwt based approach
session based approach
For either approach, my issue arises when it comes to the react native app. Since I'm not able to use the HttpOnly cookie, im not sure how to safely store data. e.g
In the jwt approach, if the server administers an access token and a refresh token, the react native client can just store them both in the same place e.g https://github.com/mcodex/react-native-sensitive-info. Which means the refresh token is just as susceptible as the access token, which defeats the point of a refresh token, so might as well just have the access token be long lived.
In the session based approach, react native can just store the session id some where (like react-native-sensitive-info above), and the same problem arises
My current thoughts on what should be done:
It seems like theres no way of getting around the security issue of storing information in react native, so as of now I feel like im just going to follow the JWT approach, and store the access + refresh token in react-native-sensitive-info. However, this does mean that the login endpoint is going to return the access + refresh token in the body of the request when the User-agent is mobile. When the user agent is web then we should be able to set an httponly cookie. The only thing that I can think of is if there is a malicious request that masks the user agent (is this possible?), and then can receive the access + refresh token in the body and will be able to do whatever with that.
Performance Aside
A session based storage approach seems much simpler overall. Yes it does store state on the backend, but if we did the JWT approach we would have to store peoples refresh tokens somewhere on the backend anyway (If theres ever a scenario where we need to invalidate peoples refresh tokens, e.g on logout or damage prevention).
This way, say we have a sessions table, when a user logs out, or if we want to invalidate sessions, all we have to do is delete rows from that table. In the JWT method, if we want to invalidate a refresh token, we have to have a blocklist table (which will only keep growing in size, since refresh tokens shouldn't expire, but I guess they can be dropped after a long period of time). However, if you have LOTS of users, the sessions table could get large, which could cause performance issues (but you could probably just drop sessions over a certain age)
/Aside
Questions:
Ive noticed mobile applications have NEVER asked me to relogin with OAuth. Does that mean they're constantly using their refresh token whenever the access token expires? If theres no clear way to store that in a secure way in mobile, do they just have super long lasting access tokens?
Is all of this thinking overkill? Is it fine to just store a super long-lasting access-token in react native and just use that all the time? Then when the user presses 'logout' we can drop that from local storage?
Would a third party auth system like auth0 manage all of this for me?
I'll try to share my experiencies in different kinds of app, this way things may get more clear.
Authentication Method
On most of the mobile applications (with web applications) I've worked with long term access tokens on the mobile side, most of applications don't require the user to login each time you open the app. Usually we store the token in a Secure Storage.
In some cases I've worked with a memory database (Redis) to put the user's session it's really fast and you don't need to query your main database each request (this was used for a high availability system, it may be overkill for most usecases)
Some very specific solutions may require more security, this will depend on your product (like banks, and transactions apps or apps the keep sensitive data) in these cases I would recommend you to login the user every time he closes the app or stays inactive for to long. (this kind of solution usually relies on fingerprint/faceId libs)
My personal opinion on this matter is to go with jwt, it's easy to maintain on the server side if you need to change backends and has a more defined pattern to follow, but that's my opinion and if you have high demand or some specific usecase this may change.
Storage
Talking about the storage options, there are some good suggestions on where to save data like tokens in a secure way on the react native docs,a good option I've used sometime would be:
https://github.com/emeraldsanto/react-native-encrypted-storage
but you can see more options and it advantages here:
https://reactnative.dev/docs/security#secure-storage
Third party libs
They usually helps with the basics if your projects has the budget and not a lot of customization on the authentication process, usually if it's a brand new project (on the back and front end) they work well.
Most of them will handle most of the hurdle for you like token renovation but you should mind the price scalability for these kind of approach
Wish success on your project.

Security for React front-end and Node back-end

I'm relatively new to the modern JavaScript web development world. I've built a very simple Node/Express back-end and a separate React front-end. My vague plan is to have users that will have permission to access certain areas of the front-end, and then have the front-end make requests to the back-end. Can the front-end and back-end share the same authentication/authorization scheme? Can they both use something like Auth0? How can I make these two secure?
I'm a little stuck and would appreciate any advice or a nudge in the right direction. I'm mostly stuck because these are two separate applications but the same "user" would technically have permissions to certain React views as well as certain Express endpoints - how they moosh together?
Thanks.
Although seems not directly related to your topic, but I would actually suggest you try Meteor if you are not planning to immediately start working on large projects (not pressing too hard on scalability).
Meteor has a builtin support for Accounts and interacts with MongoDB nicely, and it also has its own DDP protocol that simplifies API call massively. It also interacts nicely with React.
If you think Meteor might not be a good choice for yourself, you could still learn from its design policies of authorization, etc. It has quite a bit package source code that are not too difficult to understand, and should be helpful for you to learn the basic idea. (Actually, Meteor's Accounts package already implements the basic idea mentioned by another answerer, you can learn from its design principles)
When users log in to your site, issue them with an access token that they keep client side. On front-end, check if user has token and correct permissions before rendering components. On back-end, send the token as request headers to the endpoints.
I have implemented a similar case, but with the spring boot kotlin at the backend instead. My solution is using JWT token to validate the authentication and authorization.
User logins by input login form and send POST method to backend via a REST API.Backend validates credential and returns the JWT token including encrypted user_role, expiration date, etc... if valid or 403 exception
Front-end decodes the JWT (using jwt-decode lib or something else),
save it to validate the access permission to specific page in the
website based on user_role. Eg: role='ADMIN' can access to admin dashboard page, role='USER' can access user profile page, etc.
If you use express as the backend, I suggest to use the feathersjs. It has backend solutions for this and an optional front end version. Refer: https://docs.feathersjs.com/api/authentication/jwt.html
Secure Front end (React.js) and Back end (Node.js/Express Rest API) with Keycloak follow this

How do I insert data into Vue using Express, without putting the API call code in Vue?

In Vue, I understand that any Javascript included in the Vue files will be exposed to the browser (The User-agent in OAuth model). I want to make an API call to an API protected using OAuth 2 and have the data returned from the API call then displayed in the Vue app. Using OAuth, I need to use an Access token only known to the client server (node/express server) and I do not want to reveal the access token to the browser (user-agent).
I tried to see if I could do it using vue-axios, but that forces me to add the auth-token to the logic within vue, which means the browser can access the access token, which seems really unsecure.
So, I thought that I could make the API call on the node/express server that hosts the Vue application. Then, have the data included in the Vue app and send it to the user's browser with the data. The Vue app would then be rendered as normal. That would keep Auth Token hidden from the user's browser. However, I got stuck trying to include JSON data extracted from the api using Express in the Vue app.
How can I insert data into Vue using express, without putting code from the API call into vue?
Note: I'm new to Vue, so if anyone thinks that there is better way to do this securely, I'm open to suggestions.
It's possible you're trying to over-think this. You're not going to out-think the designers of OAuth. Consumers of apis need access tokens. Your OAuth access token is secure, in the sense that it can't be modified to get extra rights, and it should be short-lived, requiring regular re-authentication. You security lies in the fact that even if your user recovers the token, it won't let him do anything you're not happy for him to do anyway.

XSS Protection in Express Apps

I am developing an express app which serves as a REST api with web client and may be future mobile clients. I am using a Oauth 2.0 token authentication for both clients. This gives a good deal of security against CSRF. I want to know How to provide security against XSS.
*I made the tokens validity period very less, requiring the client to request with refresh_tokens and other client details for access_tokens. This makes it a bit safe but not entirely*.
I am concerned with the with client_id and client_secret being stolen since its present in the front-end javascript code and it being used by other client to validate. I am thinking of using a JWT for the client authentication, will this be helpful?
Data Sanitisation is another which I am confused about. There are modules like validator, express-validator which give regex validation. According to this blog post JSON Schema validations are fast. In the REST Api JSON will used for data exchange so I was wandering why can't I use modules like tv4 or any other JSON Schema validators for data validations?? I am not asking for suggestions to use what, I just want to know the basic difference in the kind of validations each provide and specially from a point of view of XSS protection and sanitisation.
So you have three separate questions here:
1) How to protect against XSS: As long as you use JSON to share data between the client & server and use standard libraries/methods for encoding/decoding JSON, you are mostly protected. After this, you only need to worry about DOM Based XSS, which is harder to be protected. But basically you need to be careful for not using any user supplied input that can be interpreted as anything other than "string" you intended. (please visit https://www.owasp.org/index.php/DOM_Based_XSS for more information)
2) client_id and client_secret being stolen: This does not seem to be possible in the way you require. In your scenario (where you distribute clientid&secret in javascript code) there is no way on server side to know whether the request is coming from your client or a fake one.
3) Data Sanitisation: I see two levels of sanitisation in the libraries you & blogpost mentioned. validator or express-validator is mostly used to validate individual data fields. Whereas others can validate a JSON object structure in addition to what "validator" does. If you require all exchanged data is in JSON format (as suggested for XSS protection as well) then you can use json object validators like tv4. (the only drawback of tv4 seems to be allowing latest json spec, which should not be a problem for you)
BTW: It would be easier if you specified your client application is purely client-side javascript (angularjs). I could not understand your question until I found this info in comments.
I have developed Restful Authentication System same as your case with NodeJS, MongoDB, ExpressJS in order to provide flexible authentication system for multiple clients like web, mobile. Let me summarize you the important points.
I have used html5 localstorage to keep user token after first time login by using login form. When user click login button, username and password sent to server and validated. After successfull validation, unique access token sent to client and stroed in local sotrage. If you have vulnerability on your client application, anyone can get your access token and make request by using your token. In order to prevent this, you need to use ssl connection for your app. This problem does not exists only restful auth systems, this can be happen in server side session storage. Let me explain this. I am using PHP for session. When user logs in, user session saved in to temp file on server and that session id sent to client browser. Somehow, if I can get that id, I can make request with header that contains someone's session id. When you compare, restful auth seems more flexible to me. I suggest you to ;
Use SSL connection prevent your access_token from to be stolen
Generate access token with powerfull encryption methods(SHA-256)
Small expire time for access_token the better
Implement a middleware for token validation for backend service usage. I mean make your requests like;
/use/update/{userid}
with custom headers contains your user token.
Design 5 attempt failed system for your backend. If user cannot success at 5 time try, this means someone tries to send random tokens in order to get in to system. Detect and block that IP
You can also deny requests other than browser clients.
Those are the informations that I have learnt while implementing the project.

SPA security using Backbone.js, Require.js and Laravel

I'm currently searching the best way for developing my next webapplication. I'm thinking about using Backbone.js and build a single page application. But I really can't imagine how to secure my app since nearly everything is done on client side. Of course I just could prevent the users from accessing my RESTful Api so they would not have access to my data. But all the view/model/collection/template js files are still accessible.
Or is there a known way to serve the js files with php (laravel), which would allow me to only serve the files I need for the respective user.
I just couldn't find a solution by searching the Web. But I just don't think that I am the lonely person who needs a clean and secure authentication method including different user rights.
Thank you in advance!
Your backend application will fetch data from a backend (= API), and probably send back some changes.
This code can't have "security holes / leaks" as long as your backend is secured.
If you are afraid of people stealing your code, you can always minify the JS (check grunt.js and almond.js for this)
To secure your backend you can make use of Laravel's auth class, and the auth filter as mentioned before.
Besides normal auth, you could implement roles, that you can assign to specific users, giving them more or less access to certain resources in your backend.
Here's the method I would try :
Separate the application in two parts.
One part - login via regular Laravel Auth on a separate page, and then when the user is logged in serve the single page app in a different view.
Wouldn't this work?
Web Services are no different than any other web application you build. At the end of the day you are exposing functionality to the client (which is also the attacker). It doesn't matter what the client is implemented in, if you expose dangerous functionality you will be hacked.
Have a session state, keep track of the user id and make sure that the user is only accessing resources they have been allowed to access.
I do not think that what JS/template files are exposed really matters. Essentially, you should only be allowing data interaction to authenticated users. Think of this as two separate applications.
The front-end application logs in, and a cookie is stored (or some other persistence is used).
The back-end application then uses the persistent authentication to validate every single user request for data, and every user action.
This way you don't have to worry about the security, the client can only fetch the data that the server allows it to, and, likewise, it can only interact with the data insofar as the server allows it. You shouldn't be relying on the client side for security anyway, even logged in, otherwise some malicious user could, conceivably, save all your frontend code and use it against you without authentication.

Resources