I'm trying to create a website using expressjs.
I want to send a different page to the user if he's logged in.
I'm able to send the raw html website, but linked files like index.css are not beeing loaded!
app.use(cookieParser());
app.use(expressSession({secret:'somesecrettokenhere', resave: false, saveUninitialized: true}));
app.use(bodyParser());
//app.use(express.static(path.join(__dirname, '../client/login')));
// disable layout
var mainPage = express.static(path.join(__dirname, '../client/main'));
var loginPage = express.static(path.join(__dirname, '../client/login'));
app.get('/', function (req, res, next) {
console.log('getting /');
if (req.session.userName) {
//app.use(express.static(path.join(__dirname, '../client/main')));
console.log("logged in");
mainPage(req, res, next);
}else {
//app.use(express.static(path.join(__dirname, '../client/login')));
console.log("not logged in");
loginPage(req, res, next);
}
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Thanks in advance!
Yes, you can.
You can do response.render(pageName); to render the page where you want to send the user.
app.use(cookieParser());
app.use(expressSession({secret:'somesecrettokenhere', resave: false, saveUninitialized: true}));
app.use(bodyParser());
//app.use(express.static(path.join(__dirname, '../client/login')));
// disable layout
// view engine setup
app.set('views', path.join(__dirname, '../client'));
app.set('view engine', 'jade');
app.get('/', function (req, res, next) {
console.log('getting /');
if (req.session.userName) {
//app.use(express.static(path.join(__dirname, '../client/main')));
console.log("logged in");
res.render("mainPage");
}else {
//app.use(express.static(path.join(__dirname, '../client/login')));
console.log("not logged in");
res.render("loginPage");
}
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
I used jade templating engine, you can use any other
It looks like the code you have is just checking a session for a user name -- I'd highly recommend AGAINST doing this, as it's not a secure way to do authentication.
If you want a secure way to do auth you should look into using a tool like either passportjs or stormpath. Stormpath does a bunch of stuff (api auth, social login, etc) in addition to the normal auth stuff, while passport is a bit more bare-bones.
Here's an example using Stormpath to do what you want:
app.get('/', function(req, res) {
if (req.user) {
res.render('template');
} else {
res.render('anonymousTemplate');
}
});
Full disclosure: I work # Stormpath and am the author of that library -- but it is awesome all the same.
Related
So I have been working with PassportJS in adding authentication to my site. I am interested in selectively displaying content that reflects whether or not a user is logged in or if he/she is an owner of a document.
I have the following files
app.js (entry point)
//Express set up
let express = require("express");
app = express();
serverPort = 8000;
io = require('socket.io')();
//BodyParser set up
bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: true }));
//Mongoose set up
mongoose = require("mongoose");
mongoose.connect("mongodb://localhost/Woof");
//Models settings
Dog = require("./models/dog");
User = require("./models/user");
//Seed file set up and run!
seed = require("./models/seed");
seed();
//Routes
app.use('/public', express.static(__dirname + '/public'));
app.use(require('./routes/dogOwners'));
app.use(require('./routes/landing'));
app.use(require('./routes/loginAndRegister'));
app.use(require('./routes/map'));
app.use(require('./routes/dog'));
//req.user avalaible to all routes
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
//App settings
app.set('port', serverPort);
app.set('view engine', 'ejs');
app.set('views', 'views');
app.set('sockets', []);
//Servloger listen:
let server = app.listen(app.get('port'), function() {
console.log('Listening on port ' + app.get('port'));
});
loginAndRegistration.js These are the authentication routes
let express = require('express');
router = express.Router({ mergeParams: true });
User = require("../models/user")
//AUTHENTICATION
let passport = require("passport");
LocalStratergy = require("passport-local");
//PASSPORT CONFIGURATION
app.use(require("express-session")({
secret: "I wanna go poopie",
resave: false,
saveUninitialized: false,
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
passport.use(new LocalStratergy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
router.get('/login', function(req,res){
res.render('login');
});
router.post('/login', passport.authenticate('local', {
successRedirect: "/main",
failureRedirect: "/login",
}), function(req, res) {
});
router.get('/logout', function(req,res){
req.logout();
res.redirect("/");
});
router.get('/register', function(req, res) {
res.render('register', {});
});
router.post("/register", function(req, res) {
User.register(new User({ username: req.body.username }), req.body.password, function(error, newlyCreatedUser) {
if (error) {
console.log("COULD NOT REGISTER USER IN THE POST ROUTE");
res.render("register");
console.log(error);
} else {
passport.authenticate("local")(req, res, function() {
let user = req.body.user;
newlyCreatedUser.name = user.name;
newlyCreatedUser.nickname = user.nickname;
newlyCreatedUser.address = user.address;
newlyCreatedUser.email = user.email;
newlyCreatedUser.numberOfDogs = user.numberOfDogs;
newlyCreatedUser.url = "/user/" + newlyCreatedUser.id;
newlyCreatedUser.save(function(error, savedUser) {
console.log("USER REGISTERED");
res.render('maps', {
gmapsCredential: credentials.gmaps,
'authorized': true
});
});
});
}
});
});
function isLoggedIn (req,res,next){
if(req.isAuthenticated()){
return next();
}
res.redirect("/login");
}
module.exports = router;
I wanna be able to call isLoggedIn in all my routes, but I can only use it in the auth routes. How do I selectively export that function alone to all my routes? I also wanna be able to refer to the varaible currentUser in all my .ejs files, however it only works in .ejs files associated with the auth routes. How do I check for currentUser in all my .ejs files?
The crux of your problems are you’ve got too much buried in your loginAndRegistration.js file.
First and foremost, if you want to run isLoggedIn for every route you need to make sure Passport is configured first i.e.
app.use(passport.initialize());
app.use(passport.session());
app.use(function(req,res,next){
res.locals.currentUser = req.user;
next();
});
passport.use(new LocalStratergy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Needs to be setup before you configure any auth middleware. This will also solve your .ejs problem as user will now be getting serialised for every route and not just the auth ones.
Finally, you can configure your middleware before any routes you want to enforce authentication on
app.use(isLoggedIn);
I am using a nodejs-express-passport solution for authentication with facebook. My goal is to automatically upload an image from a static directory the moment that a user is successfully logged in.
If my image is simply animal.png located at /images how would I modify
the following node-express server code to accomplish this?
var express = require('express');
var passport = require('passport');
var Strategy = require('passport-facebook').Strategy;
passport.use(new Strategy({
clientID: process.env.CLIENT_ID,
clientSecret: process.env.CLIENT_SECRET,
callbackURL: 'http://localhost:3000/login/facebook/return'
},
function(accessToken, refreshToken, profile, cb) {
return cb(null, profile);
}));
passport.serializeUser(function(user, cb) {
cb(null, user);
});
passport.deserializeUser(function(obj, cb) {
cb(null, obj);
});
var app = express();
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(require('cookie-parser')());
app.use(require('body-parser').urlencoded({ extended: true }));
app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }));
app.use(passport.initialize());
app.use(passport.session());
app.get('/',
function(req, res) {
res.render('home', { user: req.user });
});
app.get('/login',
function(req, res){
res.render('login');
});
app.get('/login/facebook',
passport.authenticate('facebook','user_photos'));
app.get('/login/facebook/return',
passport.authenticate('facebook', { failureRedirect: '/login' }),
function(req, res) {
res.redirect('/');
});
app.get('/profile',
require('connect-ensure-login').ensureLoggedIn(),
function(req, res){
res.render('profile', { user: req.user });
});
app.listen(3000);
For res.render('profile', {user: req.user, image: 'my image string location'})
then with your html just pass in {{image}} to wherever you are trying to src the image from.
I am not super familiar with ejs templating but it'd look something like this:
<img src={{image}} alt="MyAnimal.png" style="width:304px;height:228px;">
Or did you want it to just flash on the screen? If that's the case I think you can do something like that with the flash module.
Edit:
I'll move this up here as this was a question for posting desktop data to facebook and not just popping up a picture from the server.
Passport does authentication handshakes to allow people access to your website via login, it does not however open up all the api's to Twitter/Facebook/Google, you'll need to either make them yourself, or use ones that are pre built like this Facebook API.
https://www.npmjs.com/package/fb
My problem is with 2 files in my project: server.js (where i'am going to use the user session) and route.js(define my routes).
I've managed to get the user session in routes.js with req.user() but not in app.js with
here is the code of route.js:
module.exports = function(app, passport) {
// LOGIN
// show the login form
app.get('/', function(req, res) {
// render the page and pass in any flash data if it exists
res.render('login.ejs', { message: req.flash('loginMessage') });
});
// process the login form
app.post('/login', passport.authenticate('local-login', {
successRedirect : '/profile', // redirect to the secure profile section
failureRedirect : '/', // redirect back to the signup page if there is an error
failureFlash : true // allow flash messages
}),
function(req, res) {
if (req.body.remember) {
req.session.cookie.maxAge = 1000 * 60 * 3;
} else {
req.session.cookie.expires = false;
}
res.redirect('/');
});
// PROFILE SECTION =========================
// we will want this protected so you have to be logged in to visit
// we will use route middleware to verify this (the isLoggedIn function)
app.get('/profile', isLoggedIn, function(req, res) {
var a = req.user.Email;
console.log(a);
res.render('profile.ejs', {
user : req.user // get the user out of session and pass to template
});
});
// =====================================
// LOGOUT ==============================
// =====================================
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/');
});
};
// route middleware to make sure
function isLoggedIn(req, res, next) {
// if user is authenticated in the session, carry on
if (req.isAuthenticated())
return next();
// if they aren't redirect them to the home page
res.redirect('/');
}
and server.js :
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var passport = require('passport');
var flash = require('connect-flash');
var server = require('http').createServer(app);
// configuration ===============================================================
require('./config/passport')(passport); // pass passport for configuration
app.configure(function() {
// set up our express application
app.use(express.logger('dev')); // log every request to the console
app.use(express.cookieParser()); // read cookies (needed for auth)
app.use(express.bodyParser()); // get information from html forms
// Make the files in the public folder available to the world
app.use(express.static(__dirname + '/public'));
// Tell express where it can find the templates
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs'); // set up ejs for templating
// required for passport
app.use(express.session({ secret: 'chiftestisalwaysrunning' } )); // session secret
app.use(passport.initialize());
app.use(passport.session()); // persistent login sessions
app.use(flash()); // use connect-flash for flash messages stored in session
});
// routes ======================================================================
require('./app/routes.js')(app, passport); // load our routes and pass in our app and fully configured passport
/*i want to get the user session*/
// launch ======================================================================
server.listen(port);
console.log('The magic happens on port ' + port);
As i understood i can use sessions only inside the requests, something like:
app.get('/', function (req, res) {
if (req.session.log_in)
res.render('index.html', config);
else
res.render('authorization.html', config);
});
But if i have for example 20 or more routes so i need to write authorization check in each route? Is there something global with sessions like in php that i could check sessions before all routes and determinate and decide on follow-up actions?
Express allows a middle parameter of middleware called for that route. Use an authorization system like Passport and call it like this:
app.get('/account', ensureAuthenticated, function(req, res){
res.render('account', { user: req.user });
});
We can manage session in ExpressJS using express-session package. If you are running it in shared resource, you need to use Redis or something to keep it consistent.
Server.js
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var app = express();
app.set('views', __dirname + '/views');
app.engine('html', require('ejs').renderFile);
app.use(session({secret: 'ssshhhhh'}));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
var sess;
app.get('/',function(req,res){
sess=req.session;
//Session set when user Request our app via URL
if(sess.email)
{
/*
* This line check Session existence.
* If it existed will do some action.
*/
res.redirect('/admin');
}
else{
res.render('index.html');
}
});
app.post('/login',function(req,res){
sess=req.session;
//In this we are assigning email to sess.email variable.
//email comes from HTML page.
sess.email=req.body.email;
res.end('done');
});
app.get('/admin',function(req,res){
sess=req.session;
if(sess.email)
{
res.write('
<h1>Hello '+sess.email+'</h1>
');
res.end('Logout');
}
else
{
res.write('
<h1>Please login first.</h1>
');
res.end('Login');
}
});
app.get('/logout',function(req,res){
req.session.destroy(function(err){
if(err){
console.log(err);
}
else
{
res.redirect('/');
}
});
});
app.listen(3000,function(){
console.log("App Started on PORT 3000");
});
Read complete tutorial here : http://codeforgeek.com/2014/09/manage-session-using-node-js-express-4/
I've made a proxy using the http-proxy and express middlewares. However, it isn't forwarding PUT requests - which are essential for the application I'm proxying to. What am I doing wrong?
(The purpose of the proxy server is to provide authentication for the app behind the proxy. If there is another way to do this, I'd be grateful to know.)
var proxy = new httpProxy.RoutingProxy();
var app = express();
app.configure(function() {
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.logger());
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.session({secret: 'rupert'}));
app.use(flash());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(function(req, res) {
proxy.proxyRequest(req, res, {
host: 'localhost',
port: 8080
});
});
app.use(express.static(__dirname + '/../../public'));
});
app.get('/login', function(req, res){
res.render('login', { user: req.user, message: req.flash('error') });
});
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
app.get('/logout', function(req, res){
req.logout();
res.redirect('/')
});
app.all('/*', function(req, res, next) {
return next();
});
app.listen(3000,'localhost');
You can try using http-proxy's buffer function, as written here: https://github.com/nodejitsu/node-http-proxy/issues/180
Alternatively, there could be an issue with express doing non-standard things to the request object: See issue#153 at https://github.com/nodejitsu/node-http-proxy/issues/153
specifically this response from Marak:
"This is an express problem.
The Connect / Express middlewares are doing non-standard things to your response object, breaks streaming. Try using the raw request module instead of http-proxy.
If you need proper middleware stack, check out https://github.com/flatiron/union"
No idea if union will fix this, but it seems that express alters the request beyond what http-proxy can handle.