RESTful API with Users and Authentication via Google OAuth2? - node.js

I'm kinda new to backend development and wanted to start by creating a small API with authentication and authorization that could function as an API for a blog for different frontend implementations.
I set up an API with ExpressJS and MongoDB and created a working API so I can post blog-posts, retreive all or single blog posts, etc.
Now I wanted to add Authentication and instead of using JWT or something, I thought, it could be cool to have my users sign in via their Google-Account to post/delete blog posts, etc. Does that even make sense? I hope it does because in my head it should not differ too much from using JWT for example.
I added passport.js and it's google-oauth2 strategy.
I'm already able to create users by signing in via google, but my problem lies in the way to authenticate correctly for login and subsequent API requests.
Would I use the access- and refresh-token that I receive back from google for that? At least thats what I first thought of.
But how would that work? And next up: What if I wanted to add another way to authenticate? For example JWT or maybe Facebook-OAuth? Wouldn't that cause some issues when trying to protect my API routes because I would have different ways of authenticating (and what kind of middleware would I use then for my routes?)
I hope I made my problem clear :)

Related

Can anyone outside use my api to make requests?

I am currently learning full stack dev, and have made a simple application with React on the front end, and set up a very simple REST api on my express web server that handles certain routes.
For example api/users returns a list of users from my database and returns responses as JSON data. api/blogs can return a list of blogs in JSON with a get request, or post a blog with a post request.
I have learned and been able to implement very basic user tokenization with JWT, and so only logged in users with a valid token can make a post of a blog for example. This is done by adding their token with bearer as a Authentication header in the request, which the server verifies. This makes sense to me, however I am very confused on how the backend works or if I am doing something critically wrong.
If I go to my main page for my application, and type api/blogs it opens up a page displaying JSON data. Anyone can basically view this from my application by going to api/endpoint
I am also assuming anyone from outside can use something like Postman to send a post request to my database assuming they have the token which they got since my token is saved in storage.
This is incredibly weird to me Is this just how these things work? Or am I failing to understand something crucial?
if I wanted to progress forward and learn more about this, where or what do I do?
You have described how users authenticate to your application (with a bearer token), but what steps does your application take before issuing such a token?
Does your application keep a database of users and their passwords?
If yes, can anyone sign up by inventing a user name and password?
Do you verify an email address before admitting a new user?
Or does your application rely on an external OpenID Connect service (for example, login with your Google or Facebook account)?
If yes, can anyone with a Google or Facebook account sign up for your application?
Or must an application admin (that is, you) put the user on an "allow-list"?
To summarize: Unless you take special precautions, anyone from outside can sign up to your application and subsequently use it.

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

Retrieving OAuth2 Client from Google Passport Strategy

I am authenticating in my node.js (express) using Passport.js' Google Strategy: http://www.passportjs.org/docs/google/. The whole process works fine and I can authenticate, login, logout, handle tokens and all that jazz.
Now I have extended the scopes to include access to the authenticated user's calendar, and profile by creating a separate client and performing what I need to do in the API, however that seemed a little bizarre since it seems to be that I should be able to retrieve the already established OAuth2 client for subsequent requests. Has anyone face a similar issue?
Side note: I also got the authentication working using Service Accounts, probably that's a better route to take?
I ended up sticking to the JWT approach which was anyway the better alternative for my scenario.

Authentication strategy for REST API and mobile app

I'm creating a REST API server with Node.js and Express + MongoDB.
This API will have different mobile clients (iOS, Android) and possibly a web app later on.
I need users to login in order to perform some API requests. There are no 3rd party apps I want to connect with (no Facebook, Google etc). I also don't want to force the users to visit a webpage or anything like that in order for them to login.
From what I've seen on my many searches on SO, the best approach would be to let users login with full credentials once, send them a token in return, and use that token to verify future requests until it expires.
However, I'm not sure how to implement this.
I'm very confused with all of the different strategies. Is this done with basic authentication over HTTPS, with OAuth, OAuth 2.0, ... ? I just don't know what to use.
Also, I really don't want to reinvent the wheel here, not because I'm lazy, but mainly because of security concerns. Is there a library I could use to implement this? I've heard of Passport, but I couldn't understand if this is doable or not. This sounds like such a generic thing I'm sure there's a simple solution out there.
Thanks!
Now you can use Passport.js with JWT (JSON Web Tokens) with Passport-JWT. It's pretty easy to use.
Once a user is logged in, you send a token to the user. The token contains data about the user, like an id (encoded, of course). On the subsequent requests (at least where authentication is required) you make sure, that the client sends the token. On the server, you can see who sent the request (and e.g. check the user's authorization), just by looking at the token. For more info on how JWT work check this out.
There are different ways to send the token. Just have a look at the docs and it'll be clear. If not, this also helped me.
I feel you need to setup a Token Based Authentication process in your server, so you can make requests from different types of clients (Android, iOS, Web, etc.). Unfortunately, Passport documentation (and Passport-based tutorials) seems to be aimed for "web applications" only, so I do not think you should be using it for those purposes.
I did something similar following this great tutorial: http://code.tutsplus.com/tutorials/token-based-authentication-with-angularjs-nodejs--cms-22543
The client part in this tutorial is based on AngularJS, but can easily apply the same principles in a mobile client (it is just a matter of making HTTP requests including a token retrieved when you post in "/signin" or "/authenticate").
Good luck!
There is an example of RESTful service with oauth2 authentication: https://github.com/vedi/restifizer-example. I hope it will help.

NodeJS actually using OAuth (Twitter)

I am using node (8.14.0) and want to access the Twitter REST API v1.1.
I tried node-oauth so far and simple https, but none of them worked further then "login with twitter".
I don't just want to authenticate user's (aka sign in with twitter), I want to perform actions on the API with their access.
My problem is, I have not found a single example for node describing the actual process of retrieving the needed access/request tokens from the user and performing the API call with them.
All node-oauth examples "assume that you already have access token and access whatever". Well I do not have them, and I do not know how to get them, since I find no concrete example or documentation. Only a reference to a reference.
As I know the oauth libraries are to authenticate or authorize.
While the authentication you get back the accestoken and refreshtoken from the platform.
This tokens you have to save in your session or database.
After that you can use it in combination with other libraries.
I suggest to have a look at passport or everyauth for user authentication. They both support oauth.
in addition:
Google has a pretty good documentation about OAuth in general. I think this schema can be applied to other platforms too.
https://developers.google.com/accounts/docs/OAuth2?hl=en

Resources