I am newby in node.js and I try to implement the simplest authorization in Express. I want to set req.session.userId to users id from database. I can get user id from database using simple form and post request, but I can't set req.session.userId . The most incomprehensible thing for me - why sometimes req.session is working and sometimes is not.
My code for explanation.
in app.js:
Configure segment:
app.use(express.session({secret: 'asdads', key: 'sid', cookie: { maxAge: 600000, httpOnly: false }}));
After that I handle POST request with:
app.post('/login', routes.authorize);
My routes.authorize:
exports.authorize = function(req, res){
if(req.body){
var login = req.body.login;
var password = req.body.password;
//gET USER FROM DATABASE
db.getUser(login, password, function(err, results){
//ensure that results is correct
console.log(results);
if(err){ res.send("User not found", 500); return;}
//PLACE WITH BUG :)
req.session.userId = results[0].id;
});
}
res.render('login', { title: 'Express!' });
}
I think I couldnt set req.session.userId in this place because I access here via POST. If I am right please help me to get access to req.session in this place.
Thanks in advance.
I think the problem is that you're immediately responding to the request before your db.getUser() completes. IIRC the Express session middleware saves session changes when the response is sent, so try something like this instead:
exports.authorize = function(req, res) {
if (!req.body)
return res.render('login', { title: 'Express!' });
var login = req.body.login;
var password = req.body.password;
db.getUser(login, password, function(err, results) {
if (err)
return res.send("User not found", 500);
req.session.userId = results[0].id;
res.render('login', { title: 'Express!' });
});
}
Related
i am getting started with node.js and now I got stuck.
var mysql = require('mysql');
var dbconfig = require('../config/database');
var connection = mysql.createConnection(dbconfig.connection);
connection.query('USE ' + dbconfig.database);
app.get('/createarticle', isLoggedIn, function(req, res){
res.render('createarticle.ejs', {
user:req.user
});
});
app.post('/createarticle' , (req, res ) => {
let sql = 'INSERT INTO news SET ?'
let post = {
// author: req.user.username,
content : req.body.content,
title: req.body.title
}
connection.query(sql, post, (err, res) => {
if(err) throw err;
console.log('success');
console.log(res);
});
});
If I use req.user.username I get this error message Cannot read property 'username' of undefined.
I also tried user.username and req.user.
In my main JS I have this function that shoud always give the user if logged in.
app.get('*', function(req, res, next) {
res.locals.user = req.user || null;
next();
});
In addition to this I want to include two redirects but I don't know where to put it.
successRedirect: '/',
failureRedirect: '/createarticle',
I appreciate every answer and pacience with me. :)
I can't comment so I have to post an answer:
What does your request object look like:
app.get('/createarticle', isLoggedIn, function(req, res){
console.log('request',req)
res.render('createarticle.ejs', {
user:req.user
});
});
If you're not populating the request object in your 'GET' from your front end,
you won't have the user you are asking for.
You may want to do some handling in the front to make sure that you only send populated request objects.
Hello I am working on mock authentication in nodeJs using express framework.I am using passport-jwt and jasonwebtoken for authentication. I created api and working well on postman.But I stuck on front end side I am not able to use protected api's on front end side.In postman i send token using headers and it works well.But it does not work on front end side.How to send token and verify from front end side??
My code is:
app.post("/login", function(req, res) {
if(req.body.name && req.body.password){
var name = req.body.name;
var password = req.body.password;
}
var user = users[_.findIndex(users, {name: name})];
if( ! user ){
res.status(401).json({message:"no such user found"});
}
if(user.password === req.body.password) {
var payload = {id: user.id};
var token = jwt.sign(payload, jwtOptions.secretOrKey);
res.json({message: "ok", token: token});
} else {
res.status(401).json({message:"passwords did not match"});
}
});
and if token is valid this post method should redirect to this page
app.get("/secret", passport.authenticate('jwt', { session: false }), function(req, res){
res.json("Success! You can not see this without a token");
});
npm install cookie-parser
var cookieParser = require('cookie-parser')
app.use(cookieParser())
app.use(function (req, res, next) {
var cookie = req.cookies.jwtToken;
if (!cookie) {
res.cookie('jwtToken', theJwtTokenValue,
{ maxAge: 900000, httpOnly: true });
} else {
console.log('let's check that this is a valid cookie');
// send cookie along to the validation functions...
}
next();
});
I've built a simple RESTful API using NodeJS, Mongoose, and Express. I am using the database to store simple string quotes and am not planning to allow access to any other users to the database nor to the api.
I've read up on securing my RESTful API but it seems as if most methods focus on using a username and password to limit access. However, that seems like an overkill for such a simple API especially since i do not consider on allowing anyone else access except for requests that come from the server itself.
So I want to make it so that if anyone else tries to access the API he would be denied access. The only way the API should be accessible is from requests from the server itself i.e from the JavaScript files on the server.
I am currently learning all those things so sorry if i am not using the proper technical terminology :)
I am considering doing something like checking the IP of the person/thing trying to access the API and if that is not the ip of the server then deny access. Would something like this work and how would I got about implementing it.
EDIT: I am looking for something simple since I dont think that most people will take the time to 'hack' the API just so they can access a database of quotes.
Here is my server.js
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var Quote = require('./mongodb/models/mainModel.js');
mongoose.connect('mongodb://localhost:27017/myappdb');
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
var port = process.env.PORT || 8080;
var router = express.Router();
function grantAccess(req) {
if(req.ip === '::1' ||
req.ip === '127.0.0.1' ||
req.ip === '::ffff:127.0.0.1') {
return true;
}
return ["IP Address Unknown " + req.ip]
}
router.get('/', function(req, res) {
res.json({ message: 'hooray! welcome to our api!' });
});
router.route('/maindb')
.post(function(req, res) {
var quote = new Quote();
quote.name = req.body.name;
quote.severity = req.body.severity;
quote.createdAt = new Date();
quote.updatedAt = new Date();
quote.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Quote created!' });
});
})
.get(function(req, res) {
if(grantAccess(req) !== 'boolean')
Quote.find(function(err, quotes) {
if (err)
res.send(err);
res.json(quotes);
});
});
router.route('/maindb/:quote_id')
.get(function(req, res) {
Quote.findById(req.params.quote_id, function(err, quote) {
if (err)
res.send(err);
res.json(quote);
});
})
.put(function(req, res) {
Quote.findById(req.params.quote_id, function(err, quote) {
if (err)
res.send(err);
quote.name = req.body.name;
quote.severity = req.body.severity;
quote.updatedAt = new Date();
// save the bear
quote.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Quote updated!' });
});
});
})
.delete(function(req, res) {
Quote.remove({
_id: req.params.quote_id
}, function(err, quote) {
if (err)
res.send(err);
res.json({ message: 'Successfully deleted' });
});
});
app.use('/api', router);
app.listen(port);
console.log('Magic happens on port ' + port);
you can add apiKey in your project. It will be required if anyone hits any of your api.
exmaple:
"apiKeys": {
"web": "7fe642cabe6855cd4175937fa8fadd876c1af6b499ab941db6a8a362c0f30f97"
}
similarly you can set apikey for mobile user or accordance to requirment of project.
Link to genrate RandomKey
By this you will allow only those users who have your api key.As api key is shared by you so you will provide it to only appropriate user.
Api key checking:
You can check api key as first middleware before any request to server
example:
router.use(function(req,res,next){
var apiKey = req.get('api_key'); // assuming user will send api key in headers
// code to check api key basic comparison
})
I'm attempting to create a form to collect email addresses. The email address POSTs to /dreamjob.
When I try to access the list on /emails no error shows up but the page does not load & times out. I cannot figure out the issue. How would I change my code to correct this? Thank you!
router.post("/dreamjob", function(req, res){
//Create Email
Email.create(req.body.email, function(err, newEmail){
if(err){
res.render("station.ejs");
} else {
newEmail.save();
console.log(req.body.email)
}
});
});
//All Emails:
router.get("/emails", function(req, res){
Email.find, function(err, email){
if (err){
console.log("ERROR!");
} else {
res.render("emails", {Email: email});
}
}
});
Model:
var mongoose = require("mongoose");
var emailSchema = new mongoose.Schema({
email: String
});
module.exports = mongoose.model("Email", emailSchema);
When you create an email, you're only responding to the request in case of error, try something like this:
Email.create(req.body.email, function(err, newEmail){
if(err){
res.render("station.ejs");
} else {
newEmail.save();
console.log(req.body.email);
res.send(200); // reply to the http request here
}
});
this is probably some basic mistake but I am watching tutorial and even though I think I done everything exactly like I should after submitting login form I am redirected to the "failureRedirect" page. When I looked at source code in passport module I something.
After this:
Strategy.prototype.authenticate = function(req, options) {
options = options || {};
var username = lookup(req.body, this._usernameField) || lookup(req.query, this._usernameField);
var password = lookup(req.body, this._passwordField) || lookup(req.query, this._passwordField);
//I added:
console.log("U-> " + username);
console.log("P-> " + password);
console says
U-> null
P-> null
Then after this, rest is not executed.
if (!username || !password) {
return this.fail({ message: options.badRequestMessage || 'Missing credentials' }, 400);
}
I am not sure which parts of code should I post here. Maybe this can help
passport.use(new LocalStrategy(
function(username, password, done){
console.log("passport.use new LocalStrategy"); //never gets executed
//never gets executed
User.getUserByUsername(username, function(err, user){
if (err) throw err;
if(!user) {
console.log("Unknown user");
return done(null, false, {message: "Uknkown User"});
}
User.comparePassword(password, user.password, function(err, isMatch){
if (err) throw err;
if (isMatch) {
return done(null, user);
} else {
console.log("invalid Pass");
return done(null, false, {message: "Invalid Password"});
}
});
});
}));
router.post("/login", passport.authenticate("local", {failureRedirect:"/users/login/err", failureFlash:"invalid username or pass"}), function(req, res){
console.log("Authenticated OK");
req.flash("success", "You are logged in");
res.redirect("/xx");
});
I am not sure about the exact implementation that you are doing. Probably you are overriding the authenticate functionality using the prototype pattern.
However, Authentication using Passportjs is simple. I have done one recently in my side project. Please go through the below link with my own experience on implementing Passportjs
I have a well documented artcile that i wrote on my tech blog. Hope this helps you
// complete code for the exmaple node rest api authentication using passport
var express = require('express');
var passport = require('passport');
var passportHttp = require('passport-http');
var basicStrategy = passportHttp.BasicStrategy; // using the basic authentication
var app = express();
app.get('/',function(req,res){
res.send("There you go");
});
app.use(passport.initialize()); // initialize and use it in express
passport.use(new passportHttp.BasicStrategy(function(username,password,done) {
if(username === password){
done(null,username); //null means no error and return is the username
}
else{
return done(null,'there is no entry for you!'); // null means nothing to say,
//no error. 2nd is the custom statement business rule
}
}));
// this function hits first when there is an API call.
function ensureAuthenticated(req,res,next){
if(req.isAuthenticated()){
next();
// next redirects the user to the next api function waiting to be executed in the express framework
}else{
res.sendStatus(403); //forbidden || unauthorized
}
};
// this means all the API calls that hit via mydomain.com/api/ uses this authentication.
//session is false, because its a HTTP API call.
// setting this helps passport to skip the check if its an API call or a session web call
app.use('/api',passport.authenticate('basic',{session:false}));
// this is served the user once the authentication is a susccess
app.get('/api/data',ensureAuthenticated,function(req,res){
var somevalue = [{name: 'foo'},
{name: 'bar'},
{name: 'baz'}];
res.send(somevalue);
});
app.listen(3250);
console.log('listening to port on ' + 3250);