Best practices to implement client-server authentication - node.js

I'm looking for an best practices to implement client-server authentication (local + social).
Right now I'm developing backend & frontend separately. Earlier I did auth by next flow:
Sign in -> receive token -> call api
I need find a way to add token into blacklist also.
Tech stack: node.js (sails)
front-end: angular
Also front-end app should be available to call api of multiple servers. That means front-end app should sign in only once at main server and be available to call another api's.
I'm opened for out-of-box solutions.

If you are using JSON Web Tokens (JWTs) as your token: you can put a unique, random value as the jti claim in the token. You store these jti values in your database and use them as your blacklist.
If you would like to read about JWT best practices for Single Page Apps with APIs, please see a blog post I've written on this topic: Token Based Authentication for Single Page Apps
Regarding out-of-box solutions: I work at Stormapth and we have such a solution in our Stormpath Angular SDK.

Related

How to implement a single secure RESTful API layer for both web client and micro-services

I am currently implementing a API project using express-js.
There are multiple clients for the API. This includes a front-end web app and some backend services.
I am looking at using a normal session based management for authentication using express-session.
I am preferring this over jwt since session based + secure cookies is easier for many use cases which I would need need
Ability to revoke user access from server side
Allow only single active web session for a user
I am sure I can maintain a separate persistance table with userid + refresh_token + access_token to achieve the above.
Its just that session based gives me these in straightforward.
Now when it comes to my daemon services, I would still like them to go via API route. This will be more like Client Credentials Flow.
Since these are non-http clients, cookies will not be supported.
I am not sure how my app can API's continue to support both of them ?
The only option I have now based on readings on various blog sources is to use JWT in the cookies for the web front end and using JWT as bearer in header.
This means that
I will need to implement all the security mechanisms like token black-listing, regenerating refresh_token etc.
I will potentially lose out on main benefit of JWT of statelessness.
What are the options I have to ensure that my API layer can support both front-end web apps like react/angular and other micro services
The standard solution here is to use an API gateway:
APIs receive JWT access tokens regardless of the client, and validate them on every request
Browser clients have their own routes to APIs, and send cookies that contain or reference tokens
Mobile clients call API directly, but with opaque access tokens
APIs call each other inside the cluster using JWTs, typically by forwarding the original token from the web or mobile client
The API gateway can perform translation where required. Here are a couple of related articles:
Phantom Token Pattern
Token Handler Pattern
Done well, all of this should provide a good separation of concerns and keep application code simple.

What's the best way to authenticate and authorize a web and api solution like MERN Stack?

I'm trying to find the best way to implement authorization. At this time, only thing I need is a simple free account, but later I may include user roles for a "premium" account using a payment system like stripe.
I have already started reading and experimenting with Auth0 but then found some other ways I can do it.
Passport.js + MongoDB, I've seen some examples and work great but I think it is missing a way to control users, rules etc with a friendly panel (like Auth0)
Using Auth0 and setting up a custom database (mongoDB). Also seems to be behind a paywall.
Also found a way to use both Auth0 for authentication and Mongoose for a MongoDB database. In this one, everything is saved in mongoDB except passwords. It's also the only setup that deleting a user from Auth0 is not affecting the MongoDB (which is bad I guess).
So, some questions are
which method you think is better?
What is the difference between 2 and 3,
Is there a way to implement rules in passport (e.g. redirect new users on first login)
If I implement Passport with MongoDB, and my database has hundreds of users, how can I manage them?
A bit of a chaos question but any help would be helpful
The best authorization strategy depends of the scope of your applications in a short or long term.
Monolithic or simple web with Private login
For example, if you will have just a simple(MERN) web with a one simple backend (api rest) or a monolithic application like this mern example with an internal or private login in your organization, your authorization strategy could be as simple as :
(1*) /login express route which receive user/password, validate them in database and returns the clasic jwt token and an array of options (react routes) to which the user should have access
web app (react) must render pages whose routes match with the received routes
web app must send the received token to any api rest endpoint invocation
when api receive the invocation from react web, must validate the existence of token as a header. If not exist, must return a 403 error.
(2*) If token exist, must try to validate it (well-formed, not expired, correct signature, etc).
(3*)If its is a valid token, you must perform a last validation: Is user with "guest" role allowed to execute a DELETE to an endpoint /user/100.
(4*) Classic solution is to have some tables in your database like: user, roles, user_roles, role_permission, permission_option. Option table must have registered all your api endpoints and its method. Also this could be used to create the relation between user <:> web routes. Check this
Modern requirements
Modern and large organizations require:
Social Network Logins
Internal/External Users
Not interactive logins (robots, schedulers, etc)
Several web apps
Several Mobile apps
A lot of Api Rest
For this case, MERN app is not a good choice because is ALL-IN-ONE. Common strategy to implement the previous requirements is to have several artifacts deployed in several servers:
web app (react, vue, angular, linkstart, etc)
apis rest (nodejs + expres, java, python, etc)
authentication/authorization: oauth2 platform/provider, Identity/Access Platforms, etc
If this is your case, you must split your MERN app into several deployable artifacts: web, api and security.
Oauth2
No matter if you are concern just for login or how ensure the authentication and authorization for your webs, apis and maybe your mobile apps, you will need : OAUTH2
You could develop your own security platform taking into consideration (1*), (2*), (3*) y (4*) or use something like:
auth0
keycloack, etc
More details here: https://stackoverflow.com/a/62049409
Your questions
which method you think is better?
I think if you will use auth0, you will save time and effort. With auth0 you just need a simple express app, with some endpoints like /login, /callback, etc. Or if you use auth0 + passport.js, these endpoints are managed by passport.js
I advice you , review how OAUTH2 flow works before to use auth0 with/without passport. This link helped me a lot.
What is the difference between 2 and 3,
As I read, auth0 and another platforms offer a user management service or it can connect to your users service (AD/LDAP, database, api, etc). So
Is there a way to implement rules in passport (e.g. redirect new users on first login)
Yes. You can add some logic when callback is redirected in your nodejs with or without passport.
If I implement Passport with MongoDB, and my database has hundreds of users, how can I manage them?
Nowadays database support a lot of rows. So for your production database try to optimize or monitor it. Another option is to hire a database administrator to perform these tasks.
References
https://www.digitalocean.com/community/tutorials/an-introduction-to-oauth-2
https://auth0.com/user-management
https://stackoverflow.com/a/62049409
https://fiware-tutorials.readthedocs.io/en/latest/roles-permissions/index.html
https://dba.stackexchange.com/questions/36935/best-relational-database-structure-for-this-data
https://www.mind-it.info/2010/01/09/nist-rbac-data-model/
Managing single sign on using passportjs for my own web applications - sharing login
https://aws.amazon.com/blogs/apn/how-to-integrate-rest-apis-with-single-page-apps-and-secure-them-using-auth0-part-1/
Facebook OAuth security using passport-facebook
Asynchronous Django, Ajax, Jquery Information
relational models

Is there a way to use CSRF protection and JWT in a sails app together but not at the same time?

I'm working on an application using sails. web and mobile.
I want to use CSRF protection that sails provides when the app is visiting on the web. And if a request is send by the mobile app. send with the payload a jwt.
On the sails' documentation I found a property csrf.routesDisabled that disabled the CSRF for some routes. But that is not what I want. I'm trying to find a way to for example, check if the parameter jwt is send in the post request. And if the parameter was send then check and validate it. else, check for _csrf value of the form. Is this possible?
or the csrf protecction works before any information is send to the server?
my better choose is use jwt in the web app too?
any other good idea for solving this problem is welcome
thanks
Sounds like you've built the web app with SailsJS and you're trying to reuse the controller actions as REST endpoints for external applications.
Really what you should do, is decouple the data access from the front-end. Have an isolated REST API - using token authentication - which is used by both a web front-end (and any other applications).
For example, I'm currently working with a SailsJS REST API, used by an EmberJS front-end and an iOS app. Both front ends login using user credentials, in order to receive an authentication token. This token is then used for any future requests. A policy locks down all but the login authentication endpoint, to validate the token

WEB API authentication from different platforms

I need to create API application which will be accessed from different platforms (WEB, WPF, Mobile). The API will be hosted on Azure and client will be different websites and desktop/mobile applications. API need to know username to return user-specific information
I have some problems with authentication right now. I used idea from this thread how to do forms authentication to API, but there is a problem there, I have to authenticate each request to API, because the cookie which I created in previous request is not stored to next request.
I am thinking about creating some custom solution there: when login request to API sent with username/password return some kind of token which i will store on client and will pass with each request. In that case I can override AuthorizeAttribute and validate the token.
but I don't believe then I should create custom solution and prefer to find a way to use something Microsoft did for me.
What will be the best way to authenticate to WEB API from different platforms?
In case if I will return token, what is the best way to create it, encode it, expire it...?
There is nothing available out of box currently, to the best of my knowledge. With OWIN, there are things coming up. You can take a look at Katana source code (Microsoft.Owin.Security). For JSON Web Token, Microsoft has the JSON web token handler. More info here. The JSON Web Token Handler can both create and validate JWT. You can use the same library to issue and validate JWT respectively from the token issuer and your web API. Creating all these infrastructure is not easy. Thinktecture identity server and identity model can make these tasks easier for you. Both are open source and you can take a look at the source code in github. Check out this and this. Another good resource is Dominick's blog.

User authentication through my REST API and Facebook

I'm a bit confused about how to properly and securely authenticate users using my REST API and provide and option to authenticate using other OAuth 2.0 providers as well (e.g. Facebook, Google, etc.).
Scenario
Users interact with a web application which should consume my REST API. Users should be able to login and perform CRUD operations both using username/password and by using 3rd party services such as Facebook. I will be using SSL to encrypt the traffic to the website and the API.
Without taking the 3rd party login services in consideration and by studying the various questions already asked here on SO, I thought about handling user authentication as in the picture.
Technologies and current idea
The REST API is written using JS using NodeJS and Express. The WebApp provided through another NodeJS instance is mostly AngularJS with templates which consumes the REST API.
My current idea is to let the WebApp handle the login sequence and let Facebook save their token in my DB using the callback. But this solution smells too much of workaround!
Questions
Is the authentication sequence depicted in the image correct?
How is the above authentication sequence compared to the Resource Owner Password Credential flow in OAuth2.0? Is it worth using OAuth2.0 instead of it?
How can I integrate login through 3rd parties (i.e. Facebook)? Any suggestion or (better) example?
References
passport.js RESTful auth
Login with facebook and using oauth 2.0 for authentication of REST api calls
And many others here on SO :)
My 2 cents..
The process looks good to me.. I would re-issue the token on each sign in and also keep it inside a database so tokens can be revoked easily.
Use PassportJS. Its got support for OAuth flows and supports many 3rd party integrations like FB, Twitter, Github etc..and since its a nodejs middleware.. its integration will be very tight within your application..

Resources