So after more or less 4 hours i have finally made some of my calls to work :P
Now i have a problem here is a picture of what i am sending my server using postman:
If you cannot tell from the picture i am using form-data sending
username = arvind#myapp.com
password = pass123
Pretty standard.
The result of this is:
{
"status": 401,
"message": "Invalid credentials"
}
Now my server looks like this:
Server.js
// BASE SETUP
// =============================================================================
var express = require('express'),
bodyParser = require('body-parser');
var app = express();
var router = express.Router();
var es = require('express-sequelize');
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
// =============================================================================
//Secure
app.all('/*', function(req, res, next) {
// CORS headers
res.header("Access-Control-Allow-Origin", "*"); // restrict it to the required domain
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
// Set custom headers for CORS
res.header('Access-Control-Allow-Headers', 'Content-type,Accept,X-Access-Token,X-Key');
if (req.method == 'OPTIONS') {
res.status(200).end();
} else {
next();
}
});
var auth = require('./auth.js');
app.all('/login', auth.login);
app.all('/api/*', [require('./middlewares/validateRequest')]);
// If no route is matched by now, it must be a 404
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});
var env = app.get('env') == 'development' ? 'dev' : app.get('env');
var port = process.env.PORT || 8080;
var Sequelize = require('sequelize');
// db config
var env = "dev";
var config = require('./database.json')[env];
var password = config.password ? config.password : null;
// initialize database connection
var sequelize = new Sequelize(
config.database,
config.user,
config.password,
{
logging: console.log,
define: {
timestamps: false
}
}
);
//Init models
var division_model = require('./lb_models/division/division_model')(express,sequelize,router);
var user_model = require('./lb_models/user/user_model')(express,sequelize,router);
var team_model = require('./lb_models/Team')(express,sequelize,router);
app.use(division_model);
app.use(user_model);
app.use(team_model);
// START THE SERVER
app.listen(port);
console.log('Magic happens on port ' + port);
And my auth.js:
var jwt = require('jwt-simple');
var auth = {
login: function(req, res) {
var username = req.body.username || '';
var password = req.body.password || '';
if (username == '' || password == '') {
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
}
// Fire a query to your DB and check if the credentials are valid
var dbUserObj = auth.validate(username, password);
if (!dbUserObj)
{ // If authentication fails, we send a 401 back
res.status(401);
res.json({
"status": 401,
"message": "Invalid credentials"
});
return;
}
if (dbUserObj) {
// If authentication is success, we will generate a token
// and dispatch it to the client
res.json(genToken(dbUserObj));
}
},
validate: function(username, password) {
// spoofing the DB response for simplicity
var dbUserObj = { // spoofing a userobject from the DB.
name: 'arvind',
role: 'admin',
username: 'arvind#myapp.com'
};
return dbUserObj;
},
validateUser: function(username) {
// spoofing the DB response for simplicity
var dbUserObj = { // spoofing a userobject from the DB.
name: 'arvind',
role: 'admin',
username: 'arvind#myapp.com'
};
return dbUserObj;
}
}
// private method
function genToken(user) {
var expires = expiresIn(7); // 7 days
var token = jwt.encode({
exp: expires
}, require('../config/secret')());
return {
token: token,
expires: expires,
user: user
};
}
function expiresIn(numDays) {
var dateObj = new Date();
return dateObj.setDate(dateObj.getDate() + numDays);
}
module.exports = auth;
using the debugger in line 4 in the auth.js i am able to find that both username & password is undefined. (therefore turned into empty strings)
Can anyone tell me why this is happening ?
Try putting the Header as Content-Type: application/json in POSTMan.
Related
Trying to create a login authentication system as an entry into web development but the fetch I have to access my login functionality doesn't work. Morgan shows "POST -- ms --". (Works through Postman). As far as I can see my cors system is set up as expected. The API will respond if the passport.authenticate('local') is removed.
authenticate.js
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
var User = require('./models/user');
var JwtStrategy = require('passport-jwt').Strategy;
var ExtractJwt = require('passport-jwt').ExtractJwt;
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config.js');
exports.local = passport.use(new LocalStrategy(User.authenticate()));
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
exports.getToken = function(user) {
return jwt.sign(user, config.secretKey,
{expiresIn: 3600});
};
var opts = {};
opts.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken();
opts.secretOrKey = config.secretKey;
exports.jwtPassport = passport.use(new JwtStrategy(opts,
(jwt_payload, done) => {
console.log("JWT payload: ", jwt_payload);
User.findOne({_id: jwt_payload._id}, (err, user) => {
if (err) {
return done(err, false);
}
else if (user) {
return done(null, user);
}
else {
return done(null, false);
}
});
}));
routes
var express = require('express');
var UserRouter = express.Router();
var passport = require('passport');
var User = require('../models/user')
var authenticate = require('../authenticate');
const cors = require('./cors');
const bodyParser = require('body-parser');
UserRouter.use(bodyParser.json());
UserRouter.route('/login')
.options(cors.corsWithOptions, (req, res) => { res.sendStatus(200); })
.post(cors.cors, passport.authenticate('local'), (req, res) => {
console.log(req.body);
var token = authenticate.getToken({_id: req.user._id});
res.setHeader('Content-Type', 'application/json');
res.json({success: true, token: token, status: 'You are successfully logged in!'});
res.status(200).send()
});
module.exports = UserRouter;
mongoose schema file
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var User = new Schema ({
firstname : {
type: String,
default: ""
},
lastname: {
type: String,
default: ''
},
admin: {
type: Boolean,
default: false
}
});
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('User', User);
cors file
const express = require('express');
const cors = require('cors');
var whitelist = ['http://localhost:3000', 'http://localhost:3443']
var corsOptionsDelegate = (req, callback) => {
var corsOptions;
console.log("Validating origin");
console.log(req.header('Origin'));
if(whitelist.indexOf(req.header('Origin')) !== -1) {
corsOptions = { origin: true };
}
else {
corsOptions = { origin: false };
}
callback(null, corsOptions);
};
exports.cors = cors();
exports.corsWithOptions = cors(corsOptionsDelegate);
Front end API call
export const loginUser = (creds) => (dispatch) => {
console.log("test")
dispatch(requestLogin(creds))
console.log("attempting login")
return fetch('http://localhost:3443/users/login', {
method: 'POST',
headers: {
'Content-Type':'application/json',
},
body: JSON.stringify(creds)
})
.then(response => {
console.log("got response 1");
if(response.ok) {
return response
} else {
console.log("response errored");
var error = new Error('Error ' + response.status + ': ' + response.statusText);
error.response = response;
throw error;
}
},
error => {
console.log("errored")
throw error;
})
.then(response => response.json())
.then(response => {
console.log("got response 2");
if(response.success) {
// Successful login
localStorage.setItem('token', response.token);
localStorage.setItem('creds', JSON.stringify(creds));
// TODO dispatch success
dispatch(receiveLogin(response));
} else {
var error = new Error('Error ' + response.status);
error.response = response;
throw error;
}
})
.catch(error => dispatch(loginError(error.message)))
}
Does anyone know where I'm going wrong with this? I'm not really getting any useful error messages from my front-end so haven't included.
Terminal output upon login attempt
OPTIONS /users/login 204 3.287 ms - 0
POST /users/login - - ms - -
I have node js server which you can view here - https://github.com/Inibua/ServerNodeJS
In index.js I have the following
const express = require('express')
const cors = require('cors')
const bodyParser = require('body-parser')
const passport = require('passport')
const localSignupStrategy = require('./passport/local-signup')
const localLoginStrategy = require('./passport/local-login')
const authRoutes = require('./routes/auth')
const postRoutes = require('./routes/post')
const commentRoutes = require('./routes/comment')
const app = express()
const port = 5000
const envConfig = require('./config/environment')
require('./config/database')(envConfig)
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://roomy-hook.surge.sh');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(passport.initialize())
//app.use(cors())
passport.use('local-signup', localSignupStrategy)
passport.use('local-login', localLoginStrategy)
// routes
app.use('/auth', authRoutes)
app.use('/post', postRoutes)
app.use('/comment', commentRoutes)
app.listen(port, () => {
console.log(`Server running on port ${port}...`)
})
the app.use() which addes Access-Control-Allow-Origin is copied from here - No 'Access-Control-Allow-Origin' - Node / Apache Port Issue
I have also tried the other questions as well, but it doesn't work.
I have tried
app.use(cors())
app.use(cors({origin:"front-end-url"}))
app.use(cors({origin:null}))
app.use(cors({origin:"*"}))
as stated in other answers, but nothing works.
Here is the error I get -
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
If you want to recreate it here is the url for the front-end http://roomy-hook.surge.sh Here you need to first press Login and fill the form and press "Sign up" on the console you will see the error.
If needed here is the route for login andsignupinsideroutes/auth.js`
const express = require('express')
const passport = require('passport')
const validator = require('validator')
const userController = require('../controllers/user')
const router = new express.Router()
function validateSignupForm (payload) {
const errors = {}
let isFormValid = true
let message = ''
if (!payload || typeof payload.password !== 'string' || payload.password.trim().length < 4) {
isFormValid = false
errors.password = 'Password must have at least 4 characters.'
}
if (!payload || typeof payload.username !== 'string' || payload.username.trim().length === 0) {
isFormValid = false
errors.name = 'Please provide your name.'
}
if (!isFormValid) {
message = 'Check the form for errors.'
}
return {
success: isFormValid,
message,
errors
}
}
function validateLoginForm (payload) {
const errors = {}
let isFormValid = true
let message = ''
if (!payload || typeof payload.password !== 'string' || payload.password.trim().length === 0) {
isFormValid = false
errors.password = 'Please provide your password.'
}
if (!isFormValid) {
message = 'Check the form for errors.'
}
return {
success: isFormValid,
message,
errors
}
}
router.post('/signup', (req, res, next) => {
const validationResult = validateSignupForm(req.body)
if (!validationResult.success) {
return res.status(200).json({
success: false,
message: validationResult.message,
errors: validationResult.errors
})
}
return passport.authenticate('local-signup', (err, user) => {
if (err) {
return res.status(200).json({
success: false,
message: err
})
}
return res.status(200).json({
success: true,
user: req.body,
message: 'You have successfully signed up! Now you should be able to log in.'
})
})(req, res, next)
})
router.post('/login', (req, res, next) => {
const validationResult = validateLoginForm(req.body)
if (!validationResult.success) {
return res.status(200).json({
success: false,
message: validationResult.message,
errors: validationResult.errors
})
}
return passport.authenticate('local-login', (err, token, userData) => {
if (err) {
if (err.name === 'IncorrectCredentialsError') {
return res.status(200).json({
success: false,
message: err.message
})
}
return res.status(200).json({
success: false,
message: 'Could not process the form.'
})
}
return res.json({
success: true,
message: 'You have successfully logged in!',
token,
user: userData
})
})(req, res, next)
})
module.exports = router
add cors in option in every url.
var cors = require('cors');
router.options('/post', cors());
router.post('/post');
I have two files : server.js and user.js , I want to secure some routes in user.js with a middle-ware written in server.je.
server.js
// :::::: G E T T H E P A C K A G E W E N E E D : : : : : : : :
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var morgan = require('morgan');
var mongoose = require('mongoose');
var cors=require('cors');
var jwt = require('jsonwebtoken'); // used to create, sign, and verify tokens
var config = require('./config'); // get our config file
// ─── GET an instance of the router for api routes ────────────────────────────────────────────────────────────────────────
var apiRoutes = express.Router();
var users =require('./app/routes/users');
//
// ────────────────────────────────────────────── II ──────────────────────────────────────────────────────────────────────
// :::::: CONFIGURATION : : : : : : : :
var port = process.env.PORT || 1991; // used to create, sign, and verify tokens
mongoose.connect(config.database, { useMongoClient: true }); // connect to database
app.set('superSecret', config.secret); // secret variable
//
// ────────────────────────────────────────────── III ──────────────────────────────────────────────────────────────────────
// :::::: USE BODY PARSER SO WE CAN GET INFO FROM POST AND/OR URL PARAMETERS : : : : : : : :
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
// :::::: USE MORGAN TO LOG REQUESTS TO THE CONSOLE: : : :
app.use(morgan('dev'));
app.use(cors());
// ──────────────────────────────────────────────────────────────
// :::::: R O U T E S : : : : : : : :
// ──────────────────────────────────────────────────────────────
// ─── A P I ROUTES ────────────────────────────────────────
// :::::: MIDDLEWARE to secure route begin with /api: : : :
apiRoutes.use(function(req, res, next) {
console.log('hah');
var token = req.body.token || req.query.token || req.headers['x-access-token'];
if (token) {
// verifies secret and checks exp
jwt.verify(token, app.get('superSecret'), function(err, decoded) {
console.log([err,decoded]);
if (err) { //failed verification.
return res.json({"error": true, success:false, message:'Faild to authenticate token'});
}
req.decoded = decoded;
next(); //no error, proceed
});
} else {
// forbidden without token
return res.status(403).send({
success: false,
message: 'No token provided.'
});
}
});
apiRoutes.get('/', function(req, res) {
res.json({ message: 'Welcome to the coolest API on earth!' });
});
app.use('/api', apiRoutes);
app.use('/user', users);
// ──────────────────────────────────────────────────
// :::::: S T A R T the server: : : : : :
app.listen(port);
console.log('Magic happens at http://localhost:' + port);
user.js
const express=require('express');
const router=express.Router();
const passport= require('passport');
const jwt=require('jsonwebtoken');
var userRoutes = express.Router();
var config = require('../../config'); // get our config file
var User = require('../../app/models/User'); // get our mongoose model
//
// ─── ROUTE TO REGISTER USER ──────────────────────────────────────────────────────────────────────
//
userRoutes.post('/signup', function(req, res) {
if (!req.body.email || !req.body.password || !req.body.firstname || !req.body.lastname || !req.body.gender || !req.body.isTrainer) {
res.json({ success: false, msg: 'set up required fields' });
} else {
var newUser = new User({
email: req.body.email,
password: req.body.password,
firstname: req.body.firstname,
lastname: req.body.lastname,
gender: req.body.gender,
isTrainer: req.body.isTraine
});
User.find({ email: req.body.email}, function(err, user){
if (err) {
res.send({ success: false, msg:'authentication error'})
}
else if (user.length != 0) {
res.send({success: false, msg:'Email already exists'})
console.log(user);
}else {
// save the user
newUser.save(function(err) {
if (err) {
console.log(err);
}else {
res.send({ success: true, msg: 'Your account created successfully! ' });
}
});
}
})
}
});
userRoutes.post('/signin', function(req, res) {
User.findOne({
email: req.body.email
}, function(err, user) {
if (err) throw err;
if (!user) {
res.send({ success: false, msg: 'Check your email' });
} else {
// check if password matches
user.comparePassword(req.body.password, function(err, isMatch) {
if (isMatch && !err) {
// if user is found and password is right create a token
var token = jwt.sign(user, config.secret,{
expiresIn: 0
});
// return the information including token as JSON
res.json({
success: true,
token: token,
username: user.username
});
} else {
res.send({ success: false, msg: 'Check your password!' });
}
});
}
});
});
userRoutes.get('/users', function(req, res) {
User.find({}, function(err, users) {
res.json(users);
});
});
module.exports= userRoutes;
I want to secure the /user/users with the middle-ware so only user with token can access to. some suggestion please to do that or to change code structure
I would create a helper module that looks like this (e.g. auth.js):
module.exports=function(req,res,next){
//check user
if(valid){
next();
}else{
res.end("auth error");
}
};
So you can simply do this everywhere:
app.use("/top-secret",require("auth.js"));
app.get("/top-secret/main",...);
If you extend the helper module with some closures, it gets realy useful, e.g.:
module.exports.minLevel=function(level){
return function(req,res,next){
if(validUser && level<=user.level){
next();
}else{
res.end("auth error");
}
};
};
Use case
app.use("/admin",require("auth.js").minLevel(5));
What i need
This is a question about express.post() routing returning 404 state.
What i have
I have this code in my server.js and it is ok (ermm, i guess).
var bcrypt = require('bcryptjs');
var bodyParser = require('body-parser');
var cors = require('cors');
var express = require('express');
var jwt = require('jwt-simple');
var moment = require('moment');
var mongoose = require('mongoose');
var path = require('path');
var request = require('request');
var compress = require('compression');
var config = require('./config');
var User = mongoose.model('User', new mongoose.Schema({
futibasId: { type: String, index: true },
email: { type: String, unique: true, lowercase: true },
password: { type: String, select: false },
username: String,
fullName: String,
picture: String,
accessToken: String
}));
mongoose.connect(config.db);
var app = express();
app.set('port', process.env.PORT || 80);
app.use(compress());
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public'), { maxAge: 2628000000 }));
/*
|--------------------------------------------------------------------------
| Login Required Middleware
|--------------------------------------------------------------------------
*/
function isAuthenticated(req, res, next) {
if (!(req.headers && req.headers.authorization)) {
return res.status(400).send({ message: 'You did not provide a JSON Web Token in the Authorization header.' });
}
var header = req.headers.authorization.split(' ');
var token = header[1];
var payload = jwt.decode(token, config.tokenSecret);
var now = moment().unix();
if (now > payload.exp) {
return res.status(401).send({ message: 'Token has expired.' });
}
User.findById(payload.sub, function(err, user) {
if (!user) {
return res.status(400).send({ message: 'User no longer exists.' });
}
req.user = user;
next();
});
}
/*
|--------------------------------------------------------------------------
| Generate JSON Web Token
|--------------------------------------------------------------------------
*/
function createToken(user) {
var payload = {
exp: moment().add(14, 'days').unix(),
iat: moment().unix(),
sub: user._id
};
return jwt.encode(payload, config.tokenSecret);
}
/*
|--------------------------------------------------------------------------
| Sign in with Email
|--------------------------------------------------------------------------
*/
app.post('/auth/login', function(req, res) {
User.findOne({ email: req.body.email }, '+password', function(err, user) {
if (!user) {
return res.status(401).send({ message: { email: 'Incorrect email' } });
}
bcrypt.compare(req.body.password, user.password, function(err, isMatch) {
if (!isMatch) {
return res.status(401).send({ message: { password: 'Incorrect password' } });
}
user = user.toObject();
delete user.password;
var token = createToken(user);
res.send({ token: token, user: user });
});
});
});
My node is running on this file normally, but my routing just wont work.
What i did
I tried to debug putting this on my homepage:
<form action="http://localhost/futibas/auth/login/" method="post"><input type="hidden" value="teste" /><input value="submit" type="submit"/></form>
But when i press the submit button, i get this in my network tab:
Request URL:http://localhost/futibas/auth/login/
Request Method:POST
Status Code:404 Not Found
And if i make an ajax request, i got this return
POST http://localhost/futibas/auth/login 404 (Not Found)
I even tried to change the express.post path to absolute, but nothing.
app.post('http://localhost/futibas/auth/login', function(req, res) {
I just can't make it work. Please, someone help me! (:
...
EDIT
AS #Nonemoticoner has said, I changed
app.post('/auth/login', function(req, res) {
to
app.post('/futibas/auth/login', function(req, res) {
but still getting a 404
You created a POST routing for /auth/login - NOT /futibas/auth/login. So basically it's why it returns 404.
Solution by OP.
I installed python and used
python -m SimpleHTTPServer
into my /client directory, then, accessing via "localhost:8000" it all worked.
I'm using express-session module to handle my node.js user sessions.
By default it allows multiple sessions per user. I need limit one session per user. I came to the following solution: store user_id:session_id pairs in redis, when user logins check if session for that user_id exists and delete it then create a new one and save it to redis. Everything works excellent until I tried to stress test my server using siege. I emulated simultaneous 1000 login attempts and I see that some sessions are not cleared and still is in redis store.
This allow one user have several sessions. What am I doing wrong?
Please find some code below.
var FileStreamRotator = require('file-stream-rotator'),
app = require('express')(),
fs = require("fs"),
bodyParser = require('body-parser'),
config = require("./providers/config"),
morgan = require('morgan'), //HTTP request logger middleware for node.js
cookieParser = require('cookie-parser'),
redis = require('redis'),
session = require('express-session'),
redisStore = require('connect-redis')(session),
publicRouter = require('./routes/public.js')();
var port = process.env.PORT || config.port;
var client = redis.createClient();
app.disable('x-powered-by');
app.use(cookieParser(config.session.secret));
app.use(session(
{
secret: config.session.secret,
store: new redisStore({host: config.redis.host, port: config.redis.port, client: client}),
saveUninitialized: false, // don't create session until something stored,
resave: false // don't save session if unmodified
}
));
app.use(morgan('combined', {stream: accessLogStream}));
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
*****
app.all('/api/*', [require('./middlewares/validateRequest')]);
******
app.use('/api/public', publicRouter);
******
app.listen(port, function (err) {
if (!err) console.log('Find me on port ' + port + ' and say "Hello"');
else console.log(err);
});
auth.js
var User = require('./../models/user.js');
var Promise = require('bluebird');
var redis = require("./../providers/redis.js");
var util = require('util');
var auth = {
login: function (req, res) {
var login = req.body.login || '';
var password = req.body.password || '';
if (login === '') {
res.status(401);
res.json({
"status": 401,
"message": "login required"
});
return;
}
if (password === '') {
res.status(401);
res.json({
"status": 401,
"message": "password required"
});
return;
}
User.login(login, password)
.then(function (user) {
if (!user) {
res.status(401);
res.json({
"status": 401,
"message": "Incorrect login data."
});
}
return redis.get(util.format("usersess:%s", user.id))
.then(function (currentSession) {
if (currentSession === null) {
redis.set(util.format("usersess:%s", user.id), req.session.id)
.then(function () {
delete user.password;
req.session.user = user;
res.json({
"status": 200,
"message": "User successfully logged in."
});
});
} else {
if (currentSession !== req.session.id) {
return redis.del(util.format("sess:%s", currentSession))
.then(function () {
return redis.set(util.format("usersess:%s", user.id), req.session.id);
})
.then(function () {
delete user.password;
req.session.user = user;
res.json({
"status": 200,
"message": "User successfully logged in."
});
})
} else {
res.json({
"status": 200,
"message": "User successfully logged in."
});
}
}
})
})
.catch(function (err) {
console.log(err);
res.status(500);
res.json({
error: true,
data: {
message: err.message
}
});
});
},
logout: function (req, res) {
req.session.destroy(function (err) {
if (err) {
console.log("Can't destroy the session. See details below");
console.log(err);
res.status(500);
res.json({
"status": 500,
"message": err.message
})
} else {
res.status(200);
res.json({
"status": 200,
"message": "User successfully logged out."
})
}
});
}
};
module.exports = auth;
user model user.js
var Promise = require('bluebird'),
bcrypt = Promise.promisifyAll(require('bcrypt')),
db = require("./../providers/db.js");
var User = {
tableName: 'users',
login: function (login, password) {
if (!login || !password) throw new Error('login and password are both required');
return db.execStoredProcedure("user_get_by_login", [login.trim()])
.then(
function (rows) {
var user = rows[0][0];
return bcrypt.compareAsync(password, user.password)
.then(function (res) {
if (!res) user = null;
return user;
});
}
);
}
};
module.exports = User;
redis provider redis.js
var config = require('./../providers/config');
var Promise = require("bluebird"),
redis = require('promise-redis')(function(resolver) {
return new Promise(resolver);
}),
redisClient = redis.createClient(config.redis.port, config.redis.host),
util = require('util');
redisClient.on('connect', function () {
console.log(util.format('redis connected on %s:%s', config.redis.host, config.redis.port));
});
module.exports = redisClient;
I was unable to find the exact reason why some sessions are not deleted but after a lot of debugging and logs investigating I think it is due to node async nature. While mySQL getting operation require some time, some login actions could run in parallel and get the same values for current user session_id.
To solve this, I created middleware that check if current user session id is in redis store, if it is not--it just destroys the session and logout user asking for a new login attempt. This may be not a good solution but it completely solved the original issue.