I am working on a small app in which I just logging user using Gmail account. Problem is when user login successfully into app there is redirect to other page which gives error 404.
Directory hierarchy is like enter image description here
And Ejs files are in view folder
I When User login by google account It should be Redirected to Welcome page But it gives an error Page not found.
Default page code is below
"use strict"
const path=require("path");
const express=require("express");
const session=require("express-session");
const bodyParser=require("body-parser");
const passport = require("passport");
const db =require("./DbConnection/findCollection");
const auth = require("./auth");
const compression = require("compression");
var appDir = path.dirname(require.main.filename);
const app=express();
app.set("view engine", "ejs");
app.use(bodyParser.urlencoded({extended:true}));
//enable gzip
app.use(compression());
//enable session storage
//TODO: add connect-mongo as session storage
app.use(session({
resave: false,
saveUninitialized: false,
secret:"keyboardcat",//config.get("SECRET"),
signed: true
}));
app.all("*", (req, res, next) => {
console.log("request: " + req.url);
next();
});
//OAuth
app.use(passport.initialize());
app.use(passport.session());
app.use(auth.router);
function respond(req, res) {
return function (err, data) {
if (err) {
return res.status(400).send(err);
}
res.header("Content-Type", "application/json");
res.send(data);//JSON.stringify(data, null, 2));
};
}
function render(req,res,file,data){
res.render("master.ejs", { content: file, req: req, data: data});
}
app.get("/",(req,res,next)=>{
if(req.user){
console.log("Path is "+appDir);
// res.redirect("/views/welcome");
res.redirect("/welcome");
}
else{
console.log("Path is "+appDir);
render(req, res,"login.ejs");}
});
app.use("/views", express.static(__dirname + '/views'))
app.all("*", (req, res) => {
res.status(404).send("Page was not found, sorry!");
});
var server = app.listen(process.env.PORT || 3000, process.env.IP || "0.0.0.0", () => {
var address = server.address();
console.log(`[${(new Date().toString()).substr(0, (new Date().toString()).indexOf(" ("))}] Server started on http://${address.address}:${address.port}`);
});
To make the express able to load the view file, you should put
app.set('views', path.join(__dirname, 'views'));
instead of
app.use('/views', express.static(__dirname + '/views'));
Related
I creating e commerce project . I want to user must have account in order to proceed the checkout process . I am able to create new user with the database but the problem is even the user is login and click buy button ,Still it is showing message user must be login. I want once the user is login then user will be able to buy products..
Here is my app.js code .
'use strict';
var debug = require('debug');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var { User } = require('./db');
var session = require('express-session');
var passport = require('./passport');
var routes = require('./routes/api/index');
//var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/api', require('./routes/api').route);
//app.use('/', routes);
//app.use('/users', users);
app.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(passport.initialize());
app.use(passport.session());
app.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
app.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile'
successRedirect: '/index.html'
}));
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
Here is the user.js code .
var route = require('express').Router();
var { User } = require('../../db');
var session = require('express-session');
var passport = require('../../passport');
route.use(session({
secret: 'some very very secret thing',
resave: false,
saveUninitialized: true
}));
route.use(passport.initialize());
route.use(passport.session());
route.post('/signup', (req, res) => {
User.create({
username: req.body.username,
password: req.body.password
}).then((user) => {
if (user) {
res.redirect('/signin.html');
}
}).catch((err) => res.send("ERROR CREATING USER"));
});
route.post('/signin', passport.authenticate('local', {
failureRedirect: '/signin.html',
// successRedirect: 'profile',
successRedirect: '../../index.html'
}));
route.get('/profile', (req, res) => {
//Available to only logged in people
// Data is different (each user sees own profile)
// console.log(req)
if (req.user) {
res.json(req.user);
} else {
res.send("YOU ARE NOT LOGGED IN");
}
});
exports = module.exports = route;
Here is the screen shot when I run the project for Login page ..
Here is screen shot even user is login still displaying message first you must login.
Once the user logs in, I am trying to serve static files. I applied the answer found here and I am having difficulty implementing it.
Upon log-in, I have this inside of routes.js:
app.post('/', function(req, res){
AM.manualLogin(req.body['user'], req.body['pass'], function(e, o){
if (!o){
res.status(400).send(e);
} else {
req.session.user = o;
if (req.body['remember-me'] == 'true'){
res.cookie('user', o.user, { maxAge: 900000 });
res.cookie('pass', o.pass, { maxAge: 900000 });
}
console.log(req.session);
res.status(200).send(o);
}
});
});
where I am setting the user in the request's session.
Inside app.js I have:
var http = require('http');
var express = require('express');
var session = require('express-session');
var bodyParser = require('body-parser');
var errorHandler = require('errorhandler');
var cookieParser = require('cookie-parser');
var MongoStore = require('connect-mongo')(session);
var app = express();
app.locals.pretty = true;
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/app/server/views');
app.set('view engine', 'pug');
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(require('stylus').middleware({ src: __dirname + '/app/public' }));
function isLoggedIn( req, res, next ) {
console.log(req.session);
if (typeof req.session.user == undefined) {
res.redirect('/');
}
next();
}
app.use(express.static(__dirname + '/app/public'));
app.use('/home', isLoggedIn, express.static(__dirname + "/app/server/docs"));
app.use(session({
secret: 'faeb4453e5d14fe6f6d04637f78077c76c73d1b4',
proxy: true,
resave: true,
saveUninitialized: true,
store: new MongoStore({ url: process.env.DB_URL })
})
);
require('./app/server/routes')(app);
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});
where I am conditionally trying to render the static files for /home.
The problem resides in isLoggedIn where req.session is always undefined even though it is defined in my router function. Why is this? My log statements show that is is being set, but somehow is lost inside isLoggedIn.
One potential problem I see is your app.use(session(...)); is placed after your app.use('/home', isLoggedIn, ...);. Hence, the session is not being properly loaded in when visiting the /home path. Try placing the app.use(session(...)); middleware before the app.use('/home', isLoggedIn, ...); middleware.
This is due the fact that the execution of middleware is determined by the order of loading (i.e. if it's higher in your code, it's executed first).
I am working on a NodeJS app that has the login on a different domain / port.
In my case, I have the login server on localhost:3000 and the application on localhost:3001.
Since I am using PassportJS, when I go to localhost:3001/profile I check if the user is logged in using
function isLoggedIn(req, res, next)
{
if (req.isAuthenticated())
{
return next();
}
res.redirect('http://localhost:3000/login');
}
After login, I send and get an SMS code, I validate the code and then I get redirected back to http://localhost:3001/profile. The problem is, once back, I get redirected to the login server again.
app.post('/login', passport.authenticate('local-login',
{
successRedirect: '/sendsms',
failureRedirect: '/login',
failureFlash: true
}),
function (req, res)
{
if (req.body.remember)
{
req.session.cookie.maxAge = 1000 * 60 * 30;
}
else
{
req.session.cookie.expires = false;
}
});
From /sendsms I get redirected to /validate:
app.post('/validate', function (req, res)
{
console.log("SMS Code: " + req.body.smscode);
if (checkSMSCode(req.body.smscode, req.user))
{
console.log("OK");
res.redirect('http://localhost:3001/profile');
}
else
{
console.log("NOK");
res.redirect('/login');
}
});
This is the app.js on my authentication server:
'use strict';
var debug = require('debug');
var express = require('express');
var session = require('express-session');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var passport = require('passport');
var flash = require('connect-flash');
var helmet = require('helmet');
var request = require('request');
var connect = require('connect');
var app = express();
/*
* Connect to the database.
* Pass passport for configuration
*/
require('./config/passportHelper')(passport);
/*
* Setup the express application
*/
app.use(logger('dev'));
app.use(cookieParser());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(helmet());
// Setup ejs templating
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Setup passport sessions
app.use(session(
{
secret: 'mysecretkey',
resave: true,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(flash());
/*
* Setup the resources
*/
app.use('/css', express.static(path.join(__dirname, 'public/stylesheets')));
app.use('/js', express.static(path.join(__dirname, 'public/scripts')));
/*
* Setup the routes
*/
require('./routes/index')(app);
require('./routes/login')(app);
require('./routes/signup')(app);
require('./routes/profile')(app);
require('./routes/logout')(app);
require('./routes/redirect')(app);
require('./routes/ticketing')(app);
require('./routes/object')(app);
require('./routes/sendsms')(app);
require('./routes/validate')(app);
/*
* Catch 404 and forward to error handler.
*/
app.use(function (req, res, next)
{
var err = new Error('Not Found');
err.status = 404;
next(err);
});
/*
* Development error handler.
* Will print stacktrace.
*/
if (app.get('env') === 'development')
{
app.use(function (err, req, res, next)
{
res.status(err.status || 500);
console.log("ERROR");
res.render('error',
{
message: err.message,
error: err
});
});
}
/*
* Production error handler.
* No stacktraces leaked to user.
*/
app.use(function (err, req, res, next)
{
res.status(err.status || 500);
res.render('error',
{
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function ()
{
console.log('Express server listening on port ' + server.address().port);
debug('Express server listening on port ' + server.address().port);
});
I'm pretty sure I'm missing something very obvious, especially since it's the first time I am doing something like this (standalone authentication server) but I can't figure it out and I seem to be running around in circles.
At first, everything was designed as a single application and since /profile was on the same domain, there was no issue.
Any ideas or hints?
I am new to NodeJS and I am experiencing a problem while setting up my routes. I am using i18next, i18next-express-middleware and i18next-node-fs-backend in order to create a multilingual test website.
I would like my URL to look like the following depending on the selected language:
/fr/index, for french,
/en/index, for english,
/jp/index, for japanese.
I am currently facing at least one problem. The default route does not send me to the correct URL. I am always directed to /.
Here is my server.js file:
'use strict';
var debug = require('debug');
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');
var i18next = require('i18next');
var i18nextMiddleware = require('i18next-express-middleware');
var backend = require('i18next-node-fs-backend');
var routes = require('./routes/index');
var users = require('./routes/users');
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');
i18next
.use(backend)
.use(i18nextMiddleware.LanguageDetector)
.init({
backend: {
loadPath: __dirname + '/locales/{{lng}}/{{ns}}.json',
addPath: __dirname + '/locales/{{lng}}/{{ns}}.missing.json'
},
ns: ["ns.common"],
defaultNS: "ns.common",
fallbackNS: "ns.common",
fallbackLng: 'en',
preload: ['en', 'fr', 'jp'],
saveMissing: true,
removeLngFromUrl: false,
detection: {
order: ['path', 'session', 'querystring', 'cookie', 'header']
},
});
app.use(i18nextMiddleware.handle(i18next));
// uncomment after placing your favicon in /public
//app.use(favicon(__dirname + '/public/favicon.ico'));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, '/public')));
app.use('/', routes);
app.use('/users', users);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
// error handlers
// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}
// production error handler
// no stacktraces leaked to user
app.use(function (err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
Here is my index.js file:
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/:lng', function (req, res) {
res.header("Content-Type", "text/html; charset=utf-8");
res.render('index', {});
});
module.exports = router;
The project is articulated as follows:
locales
|_en
ns.common.json
|_fr
ns.common.json
|_jp
ns.common.json
public
|_fonts
|_images
|_javascripts
|_stylesheets
routes
index.js
user.js
views
server.js
Everything is working fine if I enter manually the URL.
Can someone help me detect what is wrong in my code?
Thanks in advance for your answers.
Edit
As pointed out by Kishan, I use the following code, in order to redirect users to the correct locale. Thus, I am using a cookie to store the locale of a user. I ddo not know if it is a safe nor the most optimized way of doing things, but it works.
Here is the index file:
'use strict';
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function (req, res) {
res.redirect(req.cookies.locale + '/index');
});
router.get('/:lng/index', function (req, res) {
res.header("Content-Type", "text/html; charset=utf-8");
res.render('index', {});
});
/* Change locale */
router.post('/locale', function (req, res) {
res.cookie('locale', req.body.locale, { maxAge: 900000, httpOnly: true });
res.json({ status: 'success', redirect: '/' + req.body.locale + '/index'});
});
module.exports = router;
You need to add a route for / (root) in the index.js.
In the above code, the route gets into index.js but not find the path for /(root).
So add the route like...
router.get('/', function (req, res) {
// YOUR LOGIC
});
in your index.js.
I am using PassportJS to authenticate users in my application. After a user logs in, the session is created, but soon after being redirected, the session appears to become undefined once again because it hasn't been saved. I found online that often times with redirects, the redirect completes before the session is saved, and so it's as if authentication never happened. The apparent solution is to use the req.session.save function so that redirects will only happen after the session is saved. However, I am getting an error log of "TypeError: req.session.save is not a function." Can somebody please help?
Here is my code for app.js.
var express = require('express'),
passport = require('passport'),
session = require('express-session'),
bodyParser = require('body-parser'),
RedisStore = require('connect-redis')(session),
redis = require('redis'),
logger = require('morgan'),
errorHandler = require('express-error-handler'),
site = require('./site'),
oauth2 = require('./oauth2'),
port = process.env.PORT || 8080;
var app = express();
var redisClient = redis.createClient(8080, 'localhost');
// use sessions for tracking logins
app.use(session({
secret: 'keyboard cat',
resave: true,
saveUninitialized: true,
store: new RedisStore({
client: redisClient,
host: "pub-redis-14280.us-central1-1-1.gce.garantiadata.com",
port: 12543,
ttl: 260
})
}));
app.use(logger('dev'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json({ type: 'application/json' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(errorHandler({ dumpExceptions: true, showStack: true }));
// use ejs as file extension for views
app.set('view engine', 'ejs');
app.use(express.static(__dirname + '/views'));
// use passport
require('./auth');
// Account linking
app.get('/', site.index);
app.get('/login', site.loginForm);
app.post('/login', site.login);
app.get('/logout', site.logout);
app.get('/authorize', oauth2.authorization);
app.post('/authorize/decision', oauth2.decision);
// set up local server
if (module === require.main) {
// [START server]
// Start the server
var server = app.listen(process.env.PORT || 8080, function () {
var port = server.address().port;
console.log('App listening on port %s', port);
});
// [END server]
}
module.exports = app;
site.js:
var passport = require('passport');
var login = require('connect-ensure-login');
// get layout
exports.index = function (req, res) {
console.log("layout loaded");
res.render('layout');
}
// get login form
exports.loginForm = function (req, res) {
console.log("login page loaded");
res.render('login');
}
// post login form
exports.login = [
passport.authenticate('local'),
function (req, res) {
req.session.save(function (err) {
res.redirect('/');
});
}
]
// logout
exports.logout = function (req, res) {
req.logout();
res.redirect('/');
}
Passport serialize/deserialize user:
passport.serializeUser(function(id, done) {
console.log("serializing user");
done(null, id);
});
passport.deserializeUser(function(id, done) {
console.log("deserializing user");
done(null, id);
});
In my passport authentication, I return the user id for simplicity, since that's all I need to represent users in my system.
In case anybody else is still having this issue (like me), try following Nathan's comment above and debug your connection to your redis/mongo/etc store.
What worked for me was I had my redis host set to http://localhost so I swapped it to 127.0.0.1 (local development of course) and everything immediately worked.