Securing HTTP endpoint using service api - node.js

Below is the code, where I am trying to authenticate using third party providers. My authentication call is a service api which is running in different servers. How can authenticate users in my code
//app.js
app.use(passport.initialize());
// Create our Express router
var router = express.Router();
router.route('/test')
.get(**<first authenticate user using service api http://localhost:1000/authenticate>**, serviceController.getData);
app.listen(2000);
//authController.js
var app = express();
var router = express.Router();
router.post("/authenticate",function(req,res){
//Using third party providers like LDAP or Facebook using Passport
res.send("User authenticated");//Token will be send
});
app.listen(1000);
//authController.js - as function call it is working
var passport = require('passport');
var BasicStrategy = require('passport-http').BasicStrategy;
passport.use(new BasicStrategy(
function (username, password, callback) {
// Success
//return callback(null, true);
}
));
exports.isAuthenticated = passport.authenticate('basic', { session: false });
Is it possible to secure my api http://localhost:2000/test using LDAP or Facebook authentication. I am looking for something similar to SSO.
Expected result
When I hit http://localhost:2000/test, a request must be made to LDAP or facebook server running in http://localhost:1000/ to validate user and send the response from "User authenticated".
Any help on this will be really helpful.

there are couple of possibilities to achieve that using node.js
Passport Facebook; https://github.com/jaredhanson/passport-facebook
LDAP for node.js; http://ldapjs.org/
Passport provides plenty of different possibilities to login: twitter, google, facebook, linkedin, instagram. They are pretty easy to implement as well.
Check it here: http://passportjs.org/docs

Related

How to authenticate angular 10 client app from node/express js using passport-google strategy?

I'm building a web app that is being used on top of microservices architecture.
Using node/express js I have implemented auth service and products service both are listening on different ports like
http://localhost:8001 for authentication service
http://localhost:8002 for products service.
Kong Gateway used to authenticate and connect the microservices with jwt. Implemented passport-jwt and passport-local strategy to authenticate the users from client side using post calls.
Finally I have implemented the google auth on server side using passport-google strategy in this below URL
http://localhost:8001/auth/google -> it directs me to google auth consent screen after sign in it is redirecting to below Url
http://localhost:8001/auth/google/callback with token. it works fine at server end.
async googlecallback(req, res, next){
passport.authenticate('google', {
session: false,
}, (err, user, message) => {
if (!user) {
return next(new UnAuthorizedException(message))
}
const token = user.generateToken()
user = UserTransformer.transform(user)
user.token = token
this.Response(res, user, message) // sending response to client using custom method
})(req, res)
}
. When I come to authenticate the user from angular app client side. I'm unable to proceed further. just struggling here. :-(
How can I authenticate the user when they click google sign in button in angular 10 on client side?
My front end app Url like http://localhost:4002/account/login
Tried to use window.open("http://localhost:8001/auth/google","_blank") method, not working as expected.
res.setHeader('x-code', 'jwthere'); header method. Also tried to pass the JWT token with URL parameter. but both seems unsecure.
http://localhost:4002/account/login?token=7wF8bit5W1Pfi5Glt1X8H0YQu8BN7OeNRcX1zbj3AGpUHaYSxLlNIjHpzuw
security is the major concern here. I want the google sign in like khanacademy social login
https://www.khanacademy.org

Single user is being logged in across all devices

I was building a project on node.js recently, I came across this bug of user authentication. The problem is that after I log in from one account, if at the same time I refresh the home page of the website from another device, it redirects to the dashboard of the first user account. In other words, a single user is getting logged in on all the devices over the network. If suppose I don't refresh the page, and I log in normally on the application, it works fine. This problem is happening, both on the localhost as well as after hosting it on Heroku. Technologies used- node.js for handling back-end views and URLs. HTML, CSS, JavaScript for the front-end. Firebase for the database and authentication. Here is the code for the login part-
const express = require("express");
const path = require("path");
//Create Router Object.
const router = express.Router();
//Main Login Page (GET)
router.get("/", (request, response) => {
response.sendFile(path.resolve("./views/html/login.html"));
});
//Main Login Page (POST)
router.post("/", (request, response) => {
let email = request.body.email;
let password = request.body.password;
firebase.auth().setPersistence(firebase.auth.Auth.Persistence.NONE);
firebase.auth().signInWithEmailAndPassword(email, password)
.then(r => {
let user = firebase.auth().currentUser;
if (user.emailVerified)
response.redirect('/dashboard');
else
response.send("<h1>Please Verify your email address.</h1>");
})
.catch(error => {
console.log(error);
response.send("<h1>Invalid Credentials</h1>");
});
});
Please can someone help me by resolve this bug in my project?
Calling firebase.auth().signInWithEmailAndPassword(email, password) signs the user in on the location wherever you call this code. Since you run this in an express.js app in Node.js, the user is signed in to that Node.js process, until you sign them out again. This is why the Firebase Authentication SDK you are using is only meant to be used in client-side applications, where this behavior is working as intended.
When integrating Firebase Authentication in a server-side process, you should use the Firebase Admin SDK. This Admin SDK has no concept of a currently logged in user, and no signInWithEmailAndPassword. Instead, if you need to know the identity of the user accessing the server-side code, you'll:
Sign the user in in their client-side app with the Firebase Authentication SDK.
Get the ID token for that user on the client, and pass that with your call to the server.
On the server, verify that ID token, to ensure the user is who they claim they are.
Then use the information on the user's identity to determine if they're authorized to access the information.
For more on this, see the Firebase documentation on verifying ID tokens.

express-session vs passport.js?

I am currently implementing email-password login functionality for a website using just express-session. Everywhere I look I see people using passport.js to authenticate requests. The below code is working for me.
app.post("/signup", function(req, res) {
var user = new userModel(req.body);
user.save();
req.session.userid = user.id; // I use this id to authenticate
}
Do I have any reason to use passport?
In NodeJS, you can authenticate in 2 ways:
Session-Based authentication
Token-Based authentication
Passport is a token-based authentication system. It uses JSON web token i.e jwt.
In your case, as you are using session-based authentication you need not use passport

How to achieve authorize the pages in MEAN stack web application?

I am being writing the schema for the Application in mongodb. Usually in asp.net with Sql, We have assigned the pages/UIs to each roles which means role have the permission (view/edit) to access the page or not. When the role login to the Application he can only view/Edit in assigned pages to that role, un assigned pages will not be shown for that role.
In c# i have restrict the role with write the code in pre_init event. In MEAN Stack application, the same I am trying with the mongoDB.
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var rolesSchema = new Schema({
role: { name: String },
accessPage: { pagename: String, view: true, Edit: true }
});
var roles= mongoose.model('roles', rolesSchema );
I'm new to MEAN stack, How we can achieve the authorisation related stuffs in MEAN stack web application.
I think what you want is the level of authorization based on the role of the user, you may want to look at passport js. With passport js you will be able to handle authorization, and you can use node middlewares to handle authorization based on user's role.
Try to store user's role in req.user. Read passport documentation to know more about req.user
Sample middleware:
var isAdmin = function (req,res,next){
if(req.user && req.user.role==='Admin')
next();
else{
return;
}
}
Use it in your node routes
router.post('/someRoute', isAdmin, function (req,res,next){
//Handle your route here
});
Hope this helps you get some idea on how to handle authorization based on role.
The simplest way to do it would be with Passport:
http://passportjs.org/
Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter, and more.
In the MEAN stack you're using Express, which supports any connect-style middleware like Passport.

Securing API Using HTTP Basic Auth

I'm looking into HTTP Basic Auth to secure my Nodejs API (using SSL too).
I'm wondering whether both a username and password are required with Basic Auth as I would just like to use a secret API key which would serve as a username. Resources I have read appear to suggest that both are required but Stripe's docs appear to suggest that just a username is sufficient:
https://stripe.com/docs/api#authentication
"Authentication to the API occurs via HTTP Basic Auth. Provide your API key as the basic auth username. You do not need to provide a password"
You can use the basicAuth middleware in express to do this http://expressjs.com/api.html#basicAuth. Just set the username(s) to the API key and the password(s) to ' ' (empty string, not double quote).
You can also use http-auth module for HTTP Basic/Digest authentication.
// Authentication module.
var auth = require('http-auth');
var basic = auth.basic({
realm: "Simon Area.",
file: __dirname + "/../data/users.htpasswd" // gevorg:gpass, Sarah:testpass ...
});
// Creating new HTTP server.
http.createServer(basic, function(req, res) {
res.end("Welcome to private area - " + req.user + "!");
}).listen(1337);

Resources