Look, i've made a mean stack app with register/login using passportjs, and it was fine, when i change to angular2(the other was on angularjs) i've made the backend side and i think it works but i dont know how to test it on the fronted side, i know it has to be something with the url in the <a href=""> but when i put the route that passport gives me, example: /auth/facebook, my aplication does nothing... well it does something, send me to the homepage :c
here is my code so far on the backend side
const FacebookStrategy = require('passport-facebook').Strategy;
const session = require('express-session');
const secret = require('../config/database')
const user = require('../models/user')
module.exports = function(app, passport){
app.use(passport.initialize());
app.use(passport.session());
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: false }
}));
passport.serializeUser(function(user, done) {
token = jwt.sign({email: user.email}, secret, {expiresIn : '24h'});
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function(err, user) {
done(err, user);
});
});
passport.use(new FacebookStrategy({
clientID: '350645212059140',
clientSecret: '8a990aec6db37cc3535f4223c235c427',
callbackURL: "http://localhost:4200/auth/facebook/callback",
profileFields: ['id','displayName','email']
},
function(accessToken, refreshToken, profile, done) {
console.log(profile);
// User.findOrCreate(..., function(err, user) {
// if (err) { return done(err); }
// done(null, user);
// });
done(null, profile)
}
));
app.get('/auth/facebook',passport.authenticate('facebook', { scope: 'email' }));
app.get('/auth/facebook/callback' , passport.authenticate('facebook', {failureRedirect: '/login'}), function(res, res){
if (err) {
console.log(err)
}else{
res.send('wi')
}
})
return passport;
}
my question is, how can i implement this on the fronted side, remember angular 4 :)
Here is pseudo code for this.
Step 1: When you are submitting your form using ngSubmit call a function for instance passportLogin().
Step 2: Now in your component use this function and do an HTTP post request to your node js(express js) URL, for example, auth/login.
Step 3: In the server side write a routing
var express = require('express'),
router = express.Router();
module.exports = function(passport){
router.post('/login', passport.authenticate('local-login', {
successRedirect: '/auth/success',
failureRedirect: '/auth/failure'
}));
}
Related
i'm using a localhost to test the passport-facebook authentication, i've been trying to implement the Auth and im getting the error mentioned above i've reviewed similar questions but none seem to help me, i've changed my dns address but to no avail,
this is my passport.js code for facebook authentication
const mongoose = require("mongoose");
const FacebookStrategy = require('passport-facebook').Strategy;
const passport = require('passport');
const User = module.exports = mongoose.model('User', facebookSchema)
var facebookSchema = mongoose.Schema
module.exports = function (_passport) {}
//serialize the user for the session
passport.serializeUser(function (user, done) {
done(null, user.id);
});
//deserialize the user
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
passport.use('facebook', new FacebookStrategy({
clientID: 'XXXXXXXXXX',
clientSecret: 'YYYYYYYYYYYYYYY',
callbackURL: " http://localhost:3000/auth/facebook/callback",
enableProof: true,
profileFields: ['id', 'displayName', 'photos', 'email']
},
function (accessToken, refreshToken, profile, done)
{ let newUser = new User();
// set the user's facebook credentials
newUser.facebook.email = profile.emails[0].value,
newUser.facebook.fullName = profile.displayName,
User.findOne({email:newUser.facebook.email }, function(err, user) {
if(!user) {
newUser.save(function(err, newUser) {
if(err) return done(err);
done(null,newUser);
});
} else {
done(null, user);
}
});
}
));
this is my index.js code for initiallizing app
const rfc = require('rfc-3986');
const express = require('express');
const bodyParser = require('body-parser');
var routes = require('./routes/routes'); //importing route
require('./models/userModel')
app = express();
port = 3000;
require("./config/db"); app.get('/success', (req, res) => res.send("You have successfully logged in"));
app.get('/error', (req, res) => res.send("error logging in"));
const passport = require("passport");
app.use(passport.initialize());
app.use(passport.session());
require('./config/passport')(passport);
app.set(rfc)
routes(app, passport);
app.set('view engine', 'ejs')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
app.listen(port,()=>{
console.log('server listening on localhost:' + port)
});
and this is my routes.js for app routing
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');`module.exports = function(app, passport) {
app.get('/auth/facebook',
passport.authenticate('facebook', {scope:"email"}));
app.get('/auth/facebook/callback',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
// Successful authentication, redirect home.
res.redirect('/success');
});
}
});
}
this is the error i get on browser
this is the same error on terminal
I have been working on a web-app similar to this https://rustbet.com. Here's some code :
passport.serializeUser(function(user, done) {
done(null, JSON.stringify(user));
});
passport.deserializeUser(function(obj, done) {
done(null, JSON.parse(obj));
});
I'm serializing the users locally.
passport.use(new SteamStrategy({
returnURL: 'http://localhost:80/auth/steam/return',
realm: 'http://localhost:80/',
apiKey: '------------------'
},
function(identifier, profile, done) {
process.nextTick(function () {
profile.identifier = identifier;
return done(null, profile);
});
}
));
Using steam passport strategy
app.use(session({
secret: '---------',
name: 'user_session',
resave: true,
saveUninitialized: true}));
Sessions
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
And here's how i'm currently using the data
How can I use the req.user object outside of a http request/ EJS template? For instance in a socket.io app that i need. I have surfed stackoverflow and found a multitude of answers but none of them were recent. Also, I'm open to any best practices that i most likely missed.
I'm trying to follow this tutorial to set up Google Oauth in my Express app using Passport.js.
Here are my routes, defined in a server.js file:
const passport = require("passport");
const express = require("express");
const app = express();
const cors = require("cors");
const bodyParser = require("body-parser");
const cookieSession = require("cookie-session");
require("./passport-setup");
app.use(cors());
// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(
cookieSession({
name: "tuto-session",
keys: ["key1", "key2"],
})
);
app.use(passport.initialize()); //initialises passport js and auth process
app.use(passport.session()); //manage using sessions
const isLoggedIn = (req, res, next) => {
if (req.user) {
next();
} else {
res.sendStatus(401);
}
};
app.get("/", (req, res) => res.send("Hello World! You're not logged in "));
// 1. You send your users to /google. This opens a google page, in passport-setup.js.
app.get(
"/google",
passport.authenticate("google", {
scope: ["profile", "email"],
})
);
app.get("auth/google/callback",
passport.authenticate("google", {
successRedirect: '/good',
failureRedirect: "/failed"
}),
function (req, res) {
res.redirect("http://localhost:19006/good");
}
);
app.get("/failed", (req, res) => res.send("You failed to log in!"));
app.get("/good", isLoggedIn, (req, res) =>
res.send(`You logged in! Welcome ${req.user.email}`)
);
app.get("/logout", (req, res) => {
req.session = null; // destroy session
req.logout(); //logout from passport
res.redirect("/"); //redirect to home.
});
app.listen(19006, () => console.log("Listening on port"));
server.js also imports passport-setup.js, where I stored the following configurations:
const passport = require('passport')
const GoogleStrategy = require('passport-google-oauth20').Strategy
// it will take the user, and take user.id. This makes the user smaller. Each time I'm directed to a route, will take the cookie in the session, go to deserializeUser
passport.serializeUser(function (user, done) {
console.log("serialise user")
done(null, user)
})
// this function takes the id, returns the user object.
passport.deserializeUser(function (user, done) {
console.log("deserialise user")
//User.findById(id, function (err, user) {
done(null, user)
//})
// so we will have the user in req.user. But for the purpose of this tutorial, no db.
})
// this /google page will take clientID, client secret to authenticate.
passport.use(new GoogleStrategy({
clientID: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
callbackURL: "http://localhost:19006/auth/google/callback",
passReqToCallback: true,
},
function (accessToken, refreshToken, profile, done) {
return done(null, profile)
}
))
When I start up my app, I go to localhost:19006/google, which redirects me to the Google Oauth's login page. However I get redirected to this link: http://localhost:19006/auth/google/callback?code=4%2F3AGyrRpoCivQNr2-7sXZDQETVzNi9JvxaOORhTmaAZoQjIHNPAf8nWqgBFkzrVprwhUF4qMo40ljxiGZLsBLn7U&scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid&authuser=0&prompt=consent#
I also get a 404 error code, with the page showing "Cannot GET /auth/google/callback".
I checked the express routes and I have defined that route, so I don't get why the app is not showing this page.
I tried adding console.log messages to the following function:
// this /google page will take clientID, client secret to authenticate.
passport.use(new GoogleStrategy({
clientID: 'MY_CLIENT_ID',
clientSecret: 'MY_CLIENT_SECRET',
callbackURL: "http://localhost:19006/auth/google/callback",
passReqToCallback: true,
},
function (accessToken, refreshToken, profile, done) {
//added a console.log here
return done(null, profile)
}
app.get("/", (req, res) => res.send("Hello World! You're not logged in "));
// 1. You send your users to /google. This opens a google page, in passport-setup.js.
app.get(
"/google",
passport.authenticate("google", {
scope: ["profile", "email"],
})
);
app.get("auth/google/callback",
passport.authenticate("google", {
successRedirect: '/good',
failureRedirect: "/failed"
}),
function (req, res) {
// added console.log here
res.redirect("http://localhost:19006/good");
}
);
But my console did not end up logging anything.
What I have tried
In Google Developer Console, I set up the Client ID for web application with the following fields:
Image of credentials
I have tried replacing localhost with 127.0.0.1 in both the routes in my code and the Google Developer Screen, but it doesn't work.
You missed "/"
app.get("/auth/google/callback",
passport.authenticate("google", {
successRedirect: '/good',
failureRedirect: "/failed"
}),
I'm creating REST APIs using NodeJS and MongoDB as a database.
I'm using passport for handling the authentication.
I'm wondering why the sessions are not persistent! Also why the deserialization is never invoked!
passport.serializeUser(function (user, done) {
done(null, user._id);
});
passport.deserializeUser(function (id, done) {
User.findById(id, function (err, user) {
console.log(user, "deserialization"); // --> Never invoked!
done(err, user);
});
});
passport.use(User.createStrategy());
app.use(
session({
secret: process.env.SECRET,
resave: false,
saveUninitialized: false,
store: new MongoStore({ mongooseConnection: mongoose.connection }) // --> Sessions has been saved to database after each login or register
})
);
app.use(passport.initialize());
app.use(passport.session());
exports.getRestaurants = async (req, res) => {
console.log(req.session); // --> Not contains any user info
console.log(req.user); // -->undefined and this is my problem
const restaurants = await liveRestaurants.find().sort({ rate: -1 });
if (!restaurants) return next();
res.status(200).json({ restaurants });
};
After my research, I concluded that it might be for the following reasons:
app.use should be in the correct order
localhost port have an effect on it "as I read"
cluster
and other
I am using Passport js for authentication in my project. At server side i am using Express js. In app.js i have configuration for passport js and the code is:
passport.use(new Strategy({
passReqToCallback: true
},
function (req, username, password, done) {
req.models.users.find({ 'user_id' : username }, function (err, user) {
if (err) { return done(err); }
if (!user[0]) {
console.log("The username is Incorrect");
return done(null, false, { message: 'Incorrect username.' });
}
if (user[0].default_password!=password) {
console.log("The Password is Incorrect");
return done(null, false, { message: 'Incorrect password.' });
}
return done(null, user);
});
}
));
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
and after this i am verifying the client request like this:
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
Till here everything is working fine.
Now i want to place this route app.post('/login',... in routes folder so i have given the path of the route in app.js like this:
var users = require('./routes/users/users');
app.use('/users', users);
My problem is: in this user route file i don't have passport configuration and i don't want to rewrite it again for all my other routes so i am thinking to place the passport configuration in a common file and reuse it but i don't know how to do it. If you have any idea please help. Thanks.
You can write a middleware, lets call it auth.js, that checks for session info and mount this for every route that you need.
'use strict';
const qs = require('querystring'),
router = require('express').Router();
router.use(function (req, res, next) {
// set this in res.locals
if (!req.user) {
return res.redirect('/?' + qs.stringify({
'r': req.originalUrl
}));
}
next();
});
module.exports = router;
If you use the above approach, you will need to add res.locals.user = req.user; in your server/app.js.
After this, you can require the above middleware on every route that needs to be authenticated.
router.verb('/path', require('./path-to-auth'));
router.verb('/path', (req, res, next) => {
// this route will only be executed if the user is authenticated
});