App/API authentication approach advice - node.js

I'm building a mobile app (Ionic/Cordova) and it will call an API (NodeJS) and I'm trying to come up with a simple and effective user authentication approach that can both:
Sign the user in to the mobile app and
Protect the API so that only a signed in user can call the API
The API can identify which user is calling it
Ideally, I'd use something like Auth0 to sign the user in to the app because I don't want to deal with passwords etc.
So I understand I can build my HTML5/Javascript app and using Auth0 and it will log the user into the app, but the part I'm trying to understand is how do I set it up so when user is logged in and their app calls the NodeJS API, the API code will know who the user is?
Can I just use the NodeJS passport module for Auth0 and just pass the tokens from the app to the API and like magic it will work? Or will I need to do something different in the API itself like build an oauth mechanism?
Any advice on how to protect the API in this scenario would be appreciated. I ideally don't want to build my own authentication/token system in the API.

Yes passport can help you to develop siple authnetication mechanism too. like username passoword. login once and stay logged in for some time.
check this tutorial
To get the tokem you have to add signin API. in the signin API you verify username and password. then generate a jwt token and pass to client.
var token = jwt.encode(user, config.secret);
Now In you mobile app At client side you can save as cookie or local storage .
window.localStorage.setItem('token', 'the-long-access-token');
Then after whenever you call API which are restricted. you pass the token. like this
var token = window.localStorage.getItem('token');
if (token) {
$.ajaxSetup({
headers: {
'x-access-token': token
}
});
}

Related

Securing REST API Calls in SPAs using MSAL.js with Azure Active Directory - How to Pass Authentication Token to Bearer Strategy

I am creating a SPA using React and Express. I am trying to include authentication using MSAL.js and have looked at Microsoft's tutorials for SPA. I've been able to implement this with React using #msal-react. While this does perform authentication, it does not protect the REST API from access by unauthenticated users.
I found the Active Directory Javascript Nodejs Web API that seems to provide a means for protecting the REST API using Passport and the Bearer strategy, but the links showing how to couple this with the client-side seem to be broken.
I'm not sure how to connect the authentication that is occurring on the client side with REST API. As I understand it, the authentication token has to be passed, but I am not sure how to pass that.
The server-side sample code has:
// API endpoint exposed
app.get("/api",
passport.authenticate('oauth-bearer', {session: false}),
(req, res) => {
console.log('Validated claims: ', req.authInfo);
// Service relies on the name claim.
res.status(200).json({
'name': req.authInfo['name'],
'issued-by': req.authInfo['iss'],
'issued-for': req.authInfo['aud'],
'scope': req.authInfo['scp']
});
}
);
What I tried to do on the client side was to get the account information:
import {
useAccount,
useMsal
} from "#azure/msal-react";
...
const { accounts } = useMsal();
const account = useAccount(accounts[0] || {});
From looking at account after authenticating, I thought account.idTokenClaims might have what is necessary, but have had no luck.
I am stuck because I am not sure if I have a fundamental misunderstanding of how the Bearer strategy works, if I am using MSAL or Passport (or both) incorrectly, or if this is a configuration issue. I appreciate the help!
When calling your protected REST API, you need to present an access token obtained by the client application (on behalf of the signed-in user). So the ID token won't do here -it's only meant for your client application as a proof of successful user authentication. (ideally, your client and service apps should be separate, each represented by an Azure AD app registration).
After authentication, you need to obtain an access token, by using one of the acquireToken* methods. You pass a token request object to that method. Here you need to specify what resources and permissions you are requesting an access token for. The access token that would work with calling your REST API shouldn't/won't work with other APIs.
The tutorial article you linked points to a sample using implicit flow. I would recommend using the more secure auth code flow.
This tutorial should cover your need. Check this section in particular.
p.s. for a React client app, see this.

How to provide authentication for a single user (Node, Express)?

I am currently working on an app with a React frontend and a Node/Express backend. There are certain functions of the app that I only want an admin user to be able to use, so I want to implement an admin login form that takes a username and password. This would be the only user that this app has.
How would I go about implementing this? I've looked at technologies like passport.js and express-basic-auth, but I'm wondering if there's a simpler way to implement this since there is only a single user. Any advice would be greatly appreciated!
If you wanna do it by yourself then whenever the user logs in the application, create an authtoken for the user and save it in the backend and send the authoken as the response for successful login. Further save the authtoken as a cookie on the frontend. Next will be while performing any action you need to send the authtoken to the server. If that authtoken is present on the server side you go on with the action or else send the response error saying that the authtoken is invalid of something like that. On loggin out of the application remember to expire the cookie and also remove the authtoken from the backend.
You can add this if you want where if the authoken provided is incorrect you can simple remove the authtoken from the backend and redirect the user to login page expiring the cookie from the frontend.

How can I use azure ad access token which is got from SPA to protect backend api?

I want to use azure AD as authentication.
If user who is in certain organization logged in from SPA, and give access token to backend, then I want to permit access from SPA.
So, I want to check if token passed from SPA is valid or not.
How can I do this?, Or Can I do this?
I want to build backend server with node.js app, and deploy backend app to app service or Azure Container Registry.
I think bearerStrategy would work.
Ref https://github.com/AzureAD/passport-azure-ad
BearerStrategy uses Bearer Token protocol to protect web resource/api.
It works in the following manner: User sends a request to the
protected web api which contains an access_token in either the
authorization header or body. Passport extracts and validates the
access_token, and propagates the claims in access_token to the verify
callback and let the framework finish the remaining authentication
procedure. On successful authentication, passport adds the user
information to req.user and passes it to the next middleware, which is
usually the business logic of the web resource/api. In case of error,
passport sends back an unauthorized response.
In the past, there was an ADAL version for node apps. I don't know if it's still valid or not, but here are useful links:
https://medium.com/#liangjunjiang/verify-and-decode-azure-activity-directory-token-bc72cf7010bc
https://learn.microsoft.com/en-us/azure/active-directory/develop/authentication-flows-app-scenarios

Authentication flow with custom token for Firebase Authentication on cloud functions

I'm creating a game in which I would like to use firebase authentication using cloud functions for logging in and registering users. Since my dev platform (GameMaker Studio 2) doesn't have the firebase sdk, I've resulted in attempting to use the firebase auth restAPI. To authenticate a user, I have to at one point create a custom token using the users uID and then use that to login. The problem with this is that I can't really understand the flow of the authentication. How could the client have knowledge beforehand on it's userID from parameters such as email and password?
Any help in understanding the flow I need to authenticate a user will be greatly appreciated.
If you're developing on node.JS, you should be able to use npm to install the firebase package -- that would simplify things greatly.
Otherwise, the overall flow of authentication should look as follows.
Client gives email and password
Pass email & password to Firebase Authentication using your HTTP request. You should receive an auth token, and a uID if authentication was successful. (see here)
Now you have an id token that you can set as a cookie in your client's browser. You can verify this cookie by storing it in your backend for each subsequent GET request to your Node server.

REST api authentication using firebase admin sdk

I have a REST api and the authentication is done using jwt tokens. To make may api more secure (users and authentication mechanism) I would like to use firebase authentication. I would like to know can we use firebase as a authentication server for my REST APIs.
My understanding is that the client app will send the username and password to the firebase server and they will provide a token. Using that token client app will send an api call to our server. I need to integrate firebase admin SDK in my server and validate the token using admin SDK to get the data from my database.
Please correct me when I am wrong.
Also, i have a concern that how to manage refresh tokens to keep my app logged in.
Please help me to integrate this in the right way, and I am using nodejs/expressjs to create the APIs.
can we use firebase as a authentication server for my REST APIs.
Yes, it's one of the services they provide: https://firebase.google.com/products/auth/
My understanding is that the client app will send the username and password to the firebase server and they will provide a token.
Correct. The usual Firebase auth is done entirely client side.
But if there is a specific auth mechanism you need such as LDAP/AD or some other form of enterprise shenanigans, then you would need to create your own tokens that the client will use to authenticate: https://firebase.google.com/docs/auth/admin/create-custom-tokens
Using that token client app will send an api call to our server.
Correct. Once the client has successfully logged in and retrieved their ID tokens, you on the server side need to verify the ID token: https://firebase.google.com/docs/auth/admin/verify-id-tokens via middleware.
Also, i have a concern that how to manage refresh tokens to keep my app logged in.
You need not worry about that so long as the client uses the appropriate method to retrieve the ID token. For example, on the Web side the client would call: https://firebase.google.com/docs/reference/js/firebase.User#getIdToken which states (emphasis mine):
Returns the current token if it has not expired, otherwise this will refresh the token and return a new one.
As you can see, the client side Firebase SDK handles everything for you. There is no need for you on the server side to keep track of ID tokens, refresh tokens, or anything really. All you need to do is verify the token, that's it.
Please see my previous answer for more details on server side verification: Firebase authentication using NodeJS

Resources