Passportjs API Endpoint Authentication and Authorization - node.js

Scenario:
I want to create a passportjs application where I authenticate by sending username and password to and API endpoint. After authentication, the API respond with a session candy. Once the client receives the candy, client can make any API calls using that candy. API will check for the candy and then return with the required response.
This is required in a mobile application, where I can call API's to authenticate and then call other API's with the candy.
Is it possible with PassportJS? I know that it works for desktop environment because passporjs configures the header with session information which is stored in the browser and is added to every request.
What needs to be done to make it work for my scenario? Will the implicit addition of session work, or I need to explicitly add the session information with each query?

Related

Login functionality from external API in React with Node.js

I’m having trouble figuring out how to get Node.js backend tokens into React.js frontend local storage. To login a user will use their credentials though an external websites API using the Oauth2 flow, this will be the only way to login into the application.
Currently, the user clicks a button which opens a new window in the authorization URL where the user will grant privilege. Once granted, the user is redirected to the backend endpoint which goes through passport.js and gets the required access and refresh tokens sent from the external API. This is then stored in a session on the backend database. What I want, instead, is to not store a session on a database but instead implement JWT and store the user’s data in local storage. With the current flow, its just not possible to do this and I haven’t found the right documentation to work it out.
There are many websites that implement it the exact way I want but tracking down the way they do it has appeared to be a challenge in on itself.
So instead of using passport.js, which was causing a plethora of issues, I decided to implement the Oauth2 flow myself. Instead of doing ALL the work in the backend, I broke the flow into different parts.
Originally, I sent the user to the backend where they would recieve an authorization token there. This turned out to be troublesome, instead, request an authorization code on the front end. For example, send the user to the Auth path and redirect the user back the the front end once privileges have been granted. Wait at the frontend callback for a code, once obtained, send a post request to the backend with that code and any other data in the body.
When obtained at the backend, trade that code for the access token and respond to the post requst with the neccassary token and any other data that needs to be sent back e.g. profile name, picture, date of birth. You can the implementn the JWT flow and no database is required to store any session or tokens, all can be stored client side securely.

Restrict API access only for my authorized client applications

My client application is a SPA built with REACT-REDUX and back-end API is nodejs with express framework.
Problem is in my client application people can access information without login
so how to authenticate my client application without actually login to my server API.
I tried to use Auth0 but for Single page web application authentication is done only through login, there is an option for machine to machine but that is not suitable to my case because my client app is static web app no server to save client id.
i have studied few articles to get over from this most of them suggest implicit grant is suitable for my case if its true how to implement implicit grant in my client and server.
I have achieved this using JWT
Provide the client a JWT token on successful login which he will have to use in header every time he needs to use API.
then every other request use a middle-ware to verify this token, if valid let him continue or else send auth failed in response

External authentication providers and authenticating requests to RESTful API

I'm working on adding google login to my web app. It's a RESTful app, so once a user is logged in, each individual request must be authenticated with a token.
Currently, I create my own tokens using JWT. I can add useful information to the token object to help with state management.
My question is: once I add google as an authentication provider, do I then need send every request to Google to be authenticated, rather than authenticating it on my own server? Do I then lose the ability to customize the content of the token?
With external authentication providers, is it normal to manage separate JWTs for calls to your RESTful API?
Normally, you'll have the login action use the third party to identify the user. Your internal code will probably create/store/fetch an app local user profile of some sort, and you'll create your JWT based on that. Further calls to your API bearing a valid token are then trusted to have already been authenticated and therefore need no further calls to the auth provider.

nodejs authentication using api

I am building an application which needs to authenticate from another application (via api)which provides response status(success, failure) and an access-token.I need simple authentication where when user supplies correct credentials, I hit the api and save the authentication user name and access-token in session and have a persistent session.I have tried looking passport http and other strategies.But I don't think they serve this use case?Kindly let me know if I am wrong and what is the easy and effective way to achieve this.
You don't need store access-token in session.
The easiest way is use JWT (JSON Web Token) - http://jwt.io. When user sends username\password credentials to your API, you check if these credentials is correct. After that you are signing JWT and respond to the client.
When client sends to you signed access-token, you can check it with passport-jwt module - https://www.npmjs.com/package/passport-jwt.

passport.js RESTful auth

How does one handle authentication (local and Facebook, for example) using passport.js, through a RESTful API instead of through a web interface?
Specific concerns are handling the passing of data from callbacks to a RESTful response (JSON) vs using a typical res.send({ data: req.data }), setting up an initial /login endpoint which redirects to Facebook (/login cannot be accessed via AJAX, because it is not a JSON response - it is a redirect to Facebook with a callback).
I've found https://github.com/halrobertson/test-restify-passport-facebook, but I'm having trouble understanding it.
Furthermore, how does passport.js store the auth credentials? The server (or is it service?) is backed by MongoDB, and I'd expect credentials (login & salted hash of pw) to be stored there, but I don't know if passport.js has this type of capability.
There are many questions asked here, and it seems that even though the questions are asked in the context of Node and passport.js the real questions are more about workflow than how to do this with a particular technology.
Let's use #Keith example setup, modified a bit for added security:
Web server at https://example.com serves a single page Javascript client app
RESTful web service at https://example.com/api provides server support to rich client app
Server implemented in Node and passport.js.
Server has a database (any kind) with a "users" table.
Username/password and Facebook Connect are offered as authentication options
Rich client makes REST requests into https://example.com/api
There may be other clients (phone apps, for example) that use the web service at https://example.com/api but do not know about the web server at https://example.com.
Note that I'm using secure HTTP. This is in my opinion a must for any service that is available in the open, since sensitive information like passwords and authorization tokens are passing between client and server.
Username/password authentication
Let's look at how plain old authentication works first.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form.
Many of the sections of this single page app haven't been populated with data due to the user not being logged in. All these sections have an event listener on a "login" event. All this is client side stuff, the server does not know of these events.
User enters his/her login and password and hits the submit button, which triggers a Javascript handler to record the username and password in client side variables. Then this handler triggers the "login" event. Again, this is all client side action, credentials were not sent to the server yet.
The listeners of the "login" event are invoked. Each of these now needs to send one or more requests to the RESTful API at https://example.com/api to obtain the user specific data to render on the page. Every single request they send to the web service will include the username and password, possibly in the form of HTTP Basic authentication, since the service being RESTful isn't allowed to maintain client state from one request to the next. Since the web service is on secure HTTP the password is safely encrypted during transit.
The web service at https://example.com/api receives a bunch of individual requests, each with authentication information. The username and password in each request is checked against the user database and if found correct the requested function executes and data is returned to the client in JSON format. If username and password do not match an error is sent to the client in the form of a 401 HTTP error code.
Instead of forcing clients to send username and password with every request you can have a "get_access_token" function in your RESTful service that takes the username and password and responds with a token, which is some sort of cryptographic hash that is unique and has some expiration date associated with it. These tokens are stored in the database with each user. Then the client sends the access token in subsequent requests. The access token will then be validated against the database instead of the username and password.
Non browser client applications like phone apps do the same as above, they ask user to enter his/her credentials, then send them (or an access token generated from them) with every request to the web service.
The important take away point from this example is that RESTful web services require authentication with every request.
An additional layer of security in this scenario would add client application authorization in addition to the user authentication. For example, if you have the web client, iOS and Android apps all using the web service you may want the server to know which of the three the client of a given request is, regardless of who the authenticated user is. This can enable your web service to restrict certain functions to specific clients. For this you could use API keys and secrets, see this answer for some ideas on that.
Facebook authentication
The workflow above does not work for Facebook connect because the login via Facebook has a third party, Facebook itself. The login procedure requires the user to be redirected to Facebook's website where credentials are entered outside of our control.
So let's see how things change:.
The user connects to https://example.com
The server serves a rich Javascript application which renders the initial page. Somehwere in the page there is a login form that includes a "Login with Facebook" button.
The user clicks the "Login with Facebook" button, which is just a link that redirects to (for example) https://example.com/auth/facebook.
The https://example.com/auth/facebook route is handled by passport.js (see the documentation)
All the user sees is that the page changes and now they are in a Facebook hosted page where they need to login and authorize our web application. This is completely outside of our control.
The user logs in to Facebook and gives permission to our application, so Facebook now redirects back to the callback URL that we configured in the passport.js setup, which following the example in the documentation is https://example.com/auth/facebook/callback
The passport.js handler for the https://example.com/auth/facebook/callback route will invoke the callback function that receives the Facebook access token and some user information from Facebook, including the user's email address.
With the email we can locate the user in our database and store the Facebook access token with it.
The last thing you do in the Facebook callback is to redirect back to the rich client application, but this time we need to pass the username and the access token to the client so that it can use them. This can be done in a number of ways. For example, Javascript variables can be added to the page through a server-side template engine, or else a cookie can be returned with this information. (thanks to #RyanKimber for pointing out the security issues with passing this data in the URL, as I initially suggested).
So now we start the single page app one more time, but the client has the username and the access token.
The client application can trigger the "login" event immediately and let the different parts of the application request the information that they need from the web service.
All the requests sent to https://example.com/api will include the Facebook access token for authentication, or the application's own access token generated from Facebook's token via a "get_access_token" function in the REST API.
The non-browser apps have it a bit more difficult here, because OAuth requires a web browser for logging in. To login from a phone or desktop app you will need to start a browser to do the redirect to Facebook, and even worse, you need a way for the browser to pass the Facebook access token back to the application via some mechanism.
I hope this answers most of the questions. Of course you can replace Facebook with Twitter, Google, or any other OAuth based authentication service.
I'd be interested to know if someone has a simpler way to deal with this.
I greatly appreciate #Miguel's explanation with the complete flow in each cases, but I'd like to add some on the Facebook Authentication part.
Facebook provides a Javascript SDK which you can use to get the access token on client-end directly, which is then passed to the server and used to further pull all the user information from Facebook. So you don't need any re-directs basically.
Moreover, you can use the same API end-point for mobile applications as well. Just use the Android / iOS SDK for Facebook, obtain the Facebook access_token on the client end and pass it to the server.
Regarding the stateless nature as explained, when get_access_token is used to generate a token and passed to the client, this token is also stored on the server. So it's as good as a session token and I believe this makes it stateful ?
Just my 2 cents..
Here is an awesome article I found that can help you authenticate with:
Facebook
Twitter
Google
Local Auth
Easy Node Authentication: Setup and Local

Resources