Use condition in express.js server - javascript

How I can use condition in my express.js server. If user login I want to change roots and side server rendering my react app. This condition dont work if(!isLoggin) if user login I change it to true, so this should render my index with react. Wher is problem ?
if(typeof(isLoggin)=='undefined'){
var isLoggin = false;
}
//roots
if(!isLoggin){
//index
app.get('/', function(req, res){
res.render("indexNotLogin",{title:''});
})
//funkcje
app.get('/funkcje', function(req, res){
res.render("funkcje",{title:'Funkcje'});
})
//zaloguj
app.get('/zaloguj', function(req, res){
res.render("zaloguj",{title:'Zaloguj siÄ™'});
})
//zaloguj
app.post('/trylogin', function(req, res){
var username = req.body.name;
var password = req.body.password;
connection.query("SELECT * FROM user WHERE username='"+username+"' AND pass='"+password+"'", function(error, rows,fields){
//callback
if(!!error){
console.log('error in query');
}else{
if(rows.length){
res.send('user zalogowany')
isLoggin=true;
}else{
res.send('user nie istnieje')
}
}
})
})
}else{
console.log("to jest true: "+isLoggin);
app.get('/', function(req, res){
res.render("index",{title:'Zaloguj sie'});
})
}
#edit /zaloguj, /funkcje this is my static roots

At first, implement login with session, not a flag.
app.post('/trylogin', function(req, res){
var username = req.body.name;
var password = req.body.password;
connection.query("SELECT * FROM user WHERE username='"+username+"' AND pass='"+password+"'", function(error, rows,fields){
if(!!error){
console.log('error in query');
}else{
if(rows.length){
res.send('user zalogowany')
req.session.user_id = put_user_id_here
}else{
res.send('user nie istnieje')
}
}
})
})
If you want to check if the user is logged in or not in order to restrict an access, it is better to implement your own Express middleware (http://expressjs.com/en/guide/using-middleware.html#middleware.router). With the authentication middleware like below, you don't have to add a condition block which wraps route definitions.
app.use(function(req, res, next) {
if (req.session.user_id) {
next();
} else {
res.status(401).send('Unauthorized')
}
});

Like this ?
function checkAuth(req, res, next) {
console.log('Jakies id: '+req.session.user_id);
if (!req.session.user_id) {
if(req.route.path=='/'){
res.render("indexNotLogin",{title:''});
}else{
res.send('You are not authorized to view this page');
}
} else {
next();
}
}
My root to after success login:
//index
app.get('/', checkAuth, function(req, res){
res.render("index",{title:''});
})

Related

Limit acces to users Node.js

I want to limit access to the /secrets route only to users
app.get("/secrets", function(req, res){
Post.find({}, function(err, posts){
res.render("secrets", {
posts: posts
});
});
});
I know it should be something like this:
app.get("/secrets", function(req, res){
if (req.isAuthenticated()){
res.render("secrets");
} else {
res.redirect("/login");
}
});
But I don't know how to proceed since I already have a callback function.
You can use middleware it goes something like this.
app.get("/secrets", secretsPermissionCheck, function(req, res){
// do your request processing
}
});
you can write below code in your middleware folder.
module.exports = function secretsPermissionCheck(req, res, next){
if(!isAuthenticated()) {
res.redirect("/login")
}else {
next();
}
}
The second code you gave is the wrapper, because first you check whether the user is authenticated. If so, then you operate normally and send a POST request to find posts, while if not, then you redirect to login.
app.get("/secrets", function(req, res){
if (req.isAuthenticated()){
//start
Post.find({}, function(err, posts){
res.render("secrets", {
posts: posts
});
});
//end
} else {
res.redirect("/login");
}
});
app.get('/secrets', checkAuthentication, function (req, res) {
Post.find({}, function (err, posts) {
res.render("secrets", {
posts: posts
});
});
});
function checkAuthentication(req, res, next) {
if (req.isAuthenticated()) {
next();
} else {
res.redirect("/login");
}
}

How to add "authorization" check to selective API's in NodeJs?

I have a react+node based project where I build all my react based components in a dist/ directory and then upload this directory to the server and serve it via nodeJS express.static() method.
server.use(express.static(__dirname + '/dist'))
I have also written a node middleware which captures every request and checks if auth token is passed to it or not.
users.use(function(req, res, next) {
const token = req.headers.authorization
if (token) {
jwt.verify(token, process.env.SECRET_KEY, function(err) {
if (err) {
res.status(400).json({message : err})
} else {
next();
}
});
} else {
res.status(400).json({message : 'Please send a token'})
}
})
But the issue that now I am facing is that, when I run URL such as http://localhost:3001/dashboard, the node middleware also captures it and check for token instead of rendering my webview.
How do I differentiate between webview requests and other server requests in nodeJS
If you need to check auth for only some specific API you can do in following 3 ways:
Write all the functions(API) that don't use auth above/before your auth check function
`
users.get('/yourAPI1', function(req, res, next) {
//Do your stuff
});
users.get('/yourAPI2', function(req, res, next) {
//Do your stuff
});
users.get('/yourAPI3', function(req, res, next) {
//Do your stuff
});
users.use(function(req, res, next) {
const token = req.headers.authorization
if (token) {
jwt.verify(token, process.env.SECRET_KEY, function(err) {
if (err) {
res.status(400).json({message : err})
} else {
next();
}
});
} else {
res.status(400).json({message : 'Please send a token'})
}
});
//Now those functions which need auth checks
users.post('/yourAPI4', function(req, res, next) {
//Do your stuff
});
users.post('/yourAPI5', function(req, res, next) {
//Do your stuff
});
`
Modify your Auth function to skip all GET API. NOTE: Use this only if you use GET to load HTML page and not to fetch data like search of any other info.
`
users.use(function(req, res, next) {
//Just a check for `GET` API
if(req.method === 'GET') {return next();}
const token = req.headers.authorization
if (token) {
jwt.verify(token, process.env.SECRET_KEY, function(err) {
if (err) {
res.status(400).json({message : err})
} else {
next();
}
});
} else {
res.status(400).json({message : 'Please send a token'})
}
});
`
Call Auth function from only those API which needs to check auth like:
`
function checkAuth (req, res, next) {
const token = req.headers.authorization
if (token) {
jwt.verify(token, process.env.SECRET_KEY, function(err) {
if (err) {
res.status(400).json({message : err})
} else {
next();
}
});
} else {
res.status(400).json({message : 'Please send a token'})
}
});
//Escaping auth check
users.get('/yourAPI6', function(req, res, next) {
//Do your stuff
});
//Need auth for this
users.get('/yourAPI7', checkAuth, function(req, res, next) {
//Do your stuff
});
users.post('/yourAPI8', function(req, res, next) {
//Do your stuff
});
users.post('/yourAPI9', checkAuth function(req, res, next) {
//Do your stuff
});
users.put('/yourAPI10', function(req, res, next) {
//Do your stuff
});
users.put('/yourAPI11', checkAuth function(req, res, next) {
//Do your stuff
});
`
Out of all these I will prefer 3rd one as It gives you flexibility to use as a function and anywhere you need it.
You need to add a redirection for all your routes to point to your index.html or whatever is your start page.
/* route to static files */
server.use('/static-route-here', express.static(__dirname + '/static-folder-here'))
/* multiple definitions of other server routes */
server.get('api/*', authMiddleWare ,(req, res) => {
/*do api stuff here*/
})
/* anything else is redirected to index.html */
server.get('*', (req, res) => {
res.sendFile(__dirname + '/index.html');
})

How can i store token value into my local javascript file

Hi am a beginner to Nodejs i have used passportjs token based authentication if the user logins it provides a token for each user i want to perform some operations based for the users who has token values for example if the user want to see the list of registered users they can view it if he has the token value. Now it provides me the token value perfectly in Postman but i don't know how to store it in a variable and call it via FRONT-END. I want do it via Front End(If he clicks the get users button) it should display the list of users.I have done that in POSTMAN it works finely i don't have an idea how to do it via frontend.
My user Code(Login/Logout)
var express = require('express');
var router = express.Router();
var User = require('../models/user');
var passport = require('passport');
var Verify = require('./verify');
/* GET users listing. */
router.route('/')
.get(Verify.verifyOrdinaryUser, function(req, res, next) {
User.find({}, function (err, users) {
if (err) throw err;
res.json(users);
});
});
router.post('/register', function(req, res, next) {
User.register(new User({ username : req.body.username }),req.body.password, function(err, user) {
if (err) {
return res.status(500).json({err: err});
}
user.save(function(err,user) {
passport.authenticate('local')(req, res, function () {
return res.status(200).json({status: 'Registration Successful!'});
});
});
});
});
router.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) {
return next(err);
}
if (!user) {
return res.status(401).json({
err: info
});
}
req.logIn(user, function(err) {
if (err) {
return res.status(500).json({
err: 'Could not log in user'
});
}
var token = Verify.getToken(user);
res.status(200).json({
status: 'Login successful!',
success: true,
token: token
});
});
})(req,res,next);
});
router.get('/logout', function(req, res) {
req.logout();
res.status(200).json({
status: 'Bye!'
});
});
module.exports = router;
Main.js File. In this main.js file i want to send that token in this get method any idea?
$(".get-users-button").click(function() {
$.ajax({
method: "GET",
url: " http://localhost:3000/users"
})
.done(function(msg) {
console.log(msg);
template(msg);
});
});
When you get back a successful response from the POST to your /login endpoint, store the token on client-side (e.g., window.localStorage.setItem('<your-namespace>-user-token', <the token goes here>);)
Then, when user clicks the 'get-users-button', get the token out of storage (e.g., window.localStorage.getItem('<your-namespace>-user-token'); and store it in a variable if you want.
Then, on your request to get users, add your { 'x-access-token': <token variable goes here> } to your request headers.
As per the documentation for Passport:
If authentication succeeds, the next handler will be invoked and the req.user property will be set to the authenticated user.
Now if I'm understanding your question correctly, you want to pass the token value you obtain from:
var token = Verify.getToken(user)
to the view in which your front-end can do something with. You can pass variables to the view using the following middleware:
app.use((req, res, next) => {
res.locals.token = Verify.getToken(req.user)
next()
}
See the documentation for res.locals for more details.
Example usage:
app.js
const express = require('express')
const app = express()
app.set('view engine', 'pug')
app.use((req, res, next) => {
res.locals.text = 'asdf'
res.locals.token = 'abc'
next()
})
app.get('/', (req, res) => {
res.render('index')
})
app.listen(3000, () => {
console.log('listening on 3000')
})
views/index.pug
doctype html
html
head
title= title
body
h1= text
script.
console.log('#{token}')

Can't manage redirect with node.js

I have a new error with the code below. What I'm trying to do is to build a simple login system, but I have a problem with redirecting res.redirect('/example').
When I try to redirect users the console.log says that Headers have been already sent. I know that there are other questions similar to this but I'm not able to solve this problem. Please help
The file below is the main controller:
exports.login = function(req, res){
var email = req.body.email,
password = req.body.password;
User.findOne({email: email, password: password}, function(err,obj) {
if(obj){
console.log(obj);
console.log('Access approved');
req.session.regenerate(function(){
console.log('New session printed to Sessions DB');
req.session.email = email;
res.redirect('/sec');
});
} else if(!email || !password){
console.log('Please insert data');
}else if(err){
console.log('Error');
req.session.regenerate( function(){
req.session.msg = err;
res.redirect('/login');
});
} else {
console.log('errore not authenticated user');
req.session.msg = err;
res.redirect('/login');
}
});
};
This is the Routes file:
app.post('/logUser', users.login)
And the node:
app.use('/login', function(req, res) {
res.sendFile('public/login.html', {root: __dirname });
});
Ok, finally I found the solution and it's pretty simple.
I need to add next(); to node file, like this:
app.use('/login', function(req, res, next) {
res.sendFile('public/login.html', {root: __dirname });
next();
});
Probably it happen because setting next I can change headers that have been already sent and finally I can reset it again with res.redirect

How can I log an end user into my single page application, and redirect them to the Single page application?

How can I log an end user into my single page application, and redirect them to the Single page application, using Backbone.js. Express.js and passport.js.
I have passport, mongo.db, express, and backbone all working on my application. However, upon successful login, I want to load up the single page, backbone js, web application. As of right now, I have the login system working fine. But when I go to redirect the user to the application, after successful login, for some reason it just redirects right back to the login page. I have used console log to make sure that there is nothing wrong with the login code on the server side and everything is working fine. The strange thing is that when I open chrome developer tools, and look at the headers and response, I'm getting the correct index page back, but it's not loading in the browser and the Url remains http://localhost:3000/login.
Here is the code that I suspect must somehow be the culprit:
See edit #2
I've tried both res.sendfile(__dirname + '/public/index.html'); and res.render('index', { user: req.user }); in my base ('/') route but neither of them seems to be loading the index.html. Note that public/index.html and the ejs index are essentially the same files. I started off having my entire app load up on the client side but now I'm trying to move the main index.html file over to the server side so that it can be password protected.
Please let me know if there is any questions at all that will help me better explain this problem, or if there is anymore code that you would like to see. I really want to get this thing figured out.
Edit As you can see with this screenshot of my browser, I have nothing more than simple form. When that form is submitted, I do get back the desired page in the response, but it's not loading up in the browser. I'm also getting a failed to load resource error in the console, but it's failing to load /login for some reason - even though I'm trying to load index.
Edit #2 As much as I hate to paste endless blocks of code, I think the only way to resolve this issue is to paste endless blocks of code.
So here is server.js in all it's glory - minus some of the api routes that are irrelevant:
var express = require('express')
, http = require('http')
, passport = require('passport')
, LocalStrategy = require('passport-local').Strategy
, bcrypt = require('bcrypt')
, SALT_WORK_FACTOR = 10
, mongoose = require('mongoose')
, path = require('path');
var app = express();
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(3000);
app.configure(function(){
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('ejs', require('ejs-locals'));
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(express.cookieParser('your secret here'));
app.use(express.session());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
});
app.configure('development', function(){
app.use( express.errorHandler({ dumpExceptions: true, showStack: true }));
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
//Connect to database
var db = mongoose.connect( 'mongodb://localhost/attorneyapp' );
/*
|-------------------------------------------------------------------------------
| Schemas
|-------------------------------------------------------------------------------
*/
var userSchema = mongoose.Schema({
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true},
});
// Bcrypt middleware
userSchema.pre('save', function(next) {
var user = this;
if(!user.isModified('password')) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, function(err, salt) {
if(err) return next(err);
bcrypt.hash(user.password, salt, function(err, hash) {
if(err) return next(err);
user.password = hash;
next();
});
});
});
// Password verification
userSchema.methods.comparePassword = function(candidatePassword, cb) {
bcrypt.compare(candidatePassword, this.password, function(err, isMatch) {
if(err) return cb(err);
cb(null, isMatch);
});
};
var Client = new mongoose.Schema({
first_name: String,
last_name: String,
status: String,
});
var Case = new mongoose.Schema({
case_name: String,
status: String,
});
/*
|-------------------------------------------------------------------------------
| Models
|-------------------------------------------------------------------------------
*/
var User = mongoose.model( 'User', userSchema );
var ClientModel = mongoose.model( 'Client', Client );
var CaseModel = mongoose.model( 'Case', Case );
// Seed a user
// var user = new User({ username: 'bob', email: 'bob#example.com', password: 'secret' });
// user.save(function(err) {
// if(err) {
// console.log(err);
// } else {
// console.log('user: ' + user.username + " saved.");
// }
// });
// Passport session setup.
// To support persistent login sessions, Passport needs to be able to
// serialize users into and deserialize users out of the session. Typically,
// this will be as simple as storing the user ID when serializing, and finding
// the user by ID when deserializing.
passport.serializeUser(function(user, done) {
done(null, user.id);
});
passport.deserializeUser(function(id, done) {
User.findById(id, function (err, user) {
done(err, user);
});
});
// Use the LocalStrategy within Passport.
// Strategies in passport require a `verify` function, which accept
// credentials (in this case, a username and password), and invoke a callback
// with a user object. In the real world, this would query a database;
// however, in this example we are using a baked-in set of users.
passport.use(new LocalStrategy(function(username, password, done) {
User.findOne({ username: username }, function(err, user) {
if (err) {
console.log('error: ', err);
return done(err);
}
if (!user) {
console.log('Unknown user ', username);
return done(null, false, { message: 'Unknown user ' + username });
}
user.comparePassword(password, function(err, isMatch) {
if (err){
console.log('error: ', err);
return done(err);
}
if(isMatch) {
console.log('it is a match');
return done(null, user);
} else {
console.log('invalid password');
return done(null, false, { message: 'Invalid password' });
}
});
});
}));
/*
|-------------------------------------------------------------------------------
| User
|-------------------------------------------------------------------------------
*/
// POST /login
// Use passport.authenticate() as route middleware to authenticate the
// request. If authentication fails, the user will be redirected back to the
// login page. Otherwise, the primary route function function will be called,
// which, in this example, will redirect the user to the home page.
//
// curl -v -d "username=bob&password=secret" http://127.0.0.1:3000/login
//
/***** This version has a problem with flash messages
app.post('/login',
passport.authenticate('local', { failureRedirect: '/login', failureFlash: true }),
function(req, res) {
res.redirect('/');
});
*/
// POST /login
// This is an alternative implementation that uses a custom callback to
// acheive the same functionality.
app.get('/', function(req, res){
console.log('base router is being called');
// res.sendfile(__dirname + '/public/index.html');
res.render('index');
});
app.get('/login', function(req, res) {
return res.render('login');
});
app.post('/login', function(req, res, next) {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err) }
if (!user) {
console.log('NOT USER', info.message);
req.session.messages = [info.message];
return res.redirect('/login');
}
req.logIn(user, function(err) {
if (err) { return next(err); }
console.log('YES USER is loged in');
// return res.sendfile(__dirname + '/public/index.html');
return res.redirect('/');
});
})(req, res, next);
});
app.get('/users', function(req, res){
return User.find( function( err, users ) {
if( !err ) {
return res.send( users );
} else {
return console.log( err );
}
});
});
Also, not sure if this is relevant, but here is my directory and file structure.
Try to return empty value. (undefined, actually)
I mean
res.redirect('/');
return;
instead of
return res.redirect('/');
And don't use res.render('index'... and res.sendfile(... in login! It response data from index.html to client on /login page!

Categories