如何在node.js中实现登录身份验证

时间:2011-11-03 06:07:24

标签: authentication node.js login

我正在运行此节点服务器:

var server=http.createServer(function(request, responsehttp) {
    if (request.method == 'POST') {
        var body = '';
        request.on('data', function (data) {
            body += data;
        });
        request.on('end', function () {
            var POST = qs.parse(body);
            processquery(POST, request, responsehttp);
        });
    } else {
        var url_parts = url.parse(request.url, true);
        var query = url_parts.query;
        console.log(query);
        processquery(query, request, responsehttp);
    }
});

我想为此服务器添加登录表单。所以当用户通过身份验证后会显示。

   function processquery(query, request, responsehttp){
    var returnResult = function (data){
        responsehttp.end(JSON.stringify(data));
    };

    if (!query.command) {
        fileprocess(request, responsehttp);
    }
    responsehttp.writeHead(200, {"Content-Type": "application/json"});
    switch(query.command) {
        case 'logout':
            logout(query, returnResult);
            break;
        case 'login':
            login(query, returnResult);
            break;
    }    
}

在进程查询函数中,如果没有给出任何命令,则将文件返回给客户端, 所以我可以将登录命令从客户端发送到服务器,但是当用户名密码接收登录命令时应该做什么服务器,如何处理登录请求并返回登录成功或失败,写这部分我需要帮助。

我试过的。

function login(request, callback) {
    if(request.username==users[request.username] && request.password==users[request.username].password) {
        users[request.username].auth=true;
        var data = {result:'success','message':'login successful'};
        callback(data);
    } else {
        var data = {result:'error','message':'login incorrect'};
        callback(data);
    }
}

请建议我如何在此添加会话我尝试在登录功能中添加请求变量并尝试设置request.session变量,它表示request.session未定义。

请建议我如何编写此登录模块,以便为每个用户正确维护登录验证。

7 个答案:

答案 0 :(得分:239)

以下是我使用Express.js

的方式

1)检查用户是否经过身份验证:我有一个名为CheckAuth的中间件函数,我在每个需要用户进行身份验证的路由上使用该函数:

function checkAuth(req, res, next) {
  if (!req.session.user_id) {
    res.send('You are not authorized to view this page');
  } else {
    next();
  }
}

我在我的路线中使用此功能:

app.get('/my_secret_page', checkAuth, function (req, res) {
  res.send('if you are viewing this page it means you are logged in');
});

2)登录路线:

app.post('/login', function (req, res) {
  var post = req.body;
  if (post.user === 'john' && post.password === 'johnspassword') {
    req.session.user_id = johns_user_id_here;
    res.redirect('/my_secret_page');
  } else {
    res.send('Bad user/pass');
  }
});

3)退出路线:

app.get('/logout', function (req, res) {
  delete req.session.user_id;
  res.redirect('/login');
});      

如果您想了解有关Express.js的更多信息,请访问:expressjs.com/en/guide/routing.html 如果需要更复杂的东西,请结帐everyauth(它有很多可用的身份验证方法,适用于facebook,twitter等;有关它的好教程here)。

答案 1 :(得分:6)

实际上这不是问题的答案,但这是一种更好的方法。

我建议您使用connect / express作为http服务器,因为它们可以为您节省大量时间。你显然不想重新发明轮子。在您的情况下,使用connect / express会话管理会更容易。

除了身份验证之外,我建议你使用everyauth。其中支持很多身份验证策略。非常适合快速发展。

所有这一切都可以通过文档中的一些副本粘贴轻松下来!

答案 2 :(得分:3)

添加到Farid的伪答案

考虑使用Passport.js而不是everyauth

this question的答案为差异提供了一些见解。


将用户身份验证转移到Google,Facebook或其他网站有很多好处。如果您的应用程序的要求是您可以将Passport用作您的唯一身份验证提供商,或者与传统登录一起使用,则可以使您的用户更轻松地体验。

答案 3 :(得分:2)

@alessioalex答案是新节点用户的完美演示。但无论如何,除了登录之外,很难将checkAuth中间件写入所有路由,因此最好将checkAuth从每个路由移动到app.use的一个条目。例如:

function checkAuth(req, res, next) {
  // if logined or it's login request, then go next route
  if (isLogin || (req.path === '/login' && req.method === 'POST')) {
    next()
  } else {
    res.send('Not logged in yet.')
  }
}

app.use('/', checkAuth)

答案 4 :(得分:1)

我尝试了这个答案,但它对我没有用。我还是Web开发的新手,上过使用mlab的课程,但是我更喜欢解析,这就是为什么我不得不寻找最合适的解决方案的原因。这是我目前在expressJS上使用parse的解决方案。

1)检查用户是否已通过身份验证:我有一个名为isLogginIn的中间件函数,该函数在需要验证用户身份的每条路由上使用:

 function isLoggedIn(req, res, next) {
 var currentUser = Parse.User.current();
 if (currentUser) {
     next()
 } else {
     res.send("you are not authorised");
 }
}

我在这样的路线中使用此功能:

  app.get('/my_secret_page', isLoggedIn, function (req, res) 
  {
    res.send('if you are viewing this page it means you are logged in');
  });

2)登录路径:

  // handling login logic
  app.post('/login', function(req, res) {
  Parse.User.enableUnsafeCurrentUser();
  Parse.User.logIn(req.body.username, req.body.password).then(function(user) {
    res.redirect('/books');
  }, function(error) {
    res.render('login', { flash: error.message });
  });
});

3)注销路径:

 // logic route
  app.get("/logout", function(req, res){
   Parse.User.logOut().then(() => {
    var currentUser = Parse.User.current();  // this will now be null
    });
        res.redirect('/login');
   });

这对我来说非常有效,我在https://docs.parseplatform.org/js/guide/#users

处完全参考了文档。

感谢@alessioalex的回答。我只更新了最新的做法。

答案 5 :(得分:1)

======authorization====== MIDDLEWARE

const jwt = require('../helpers/jwt')
const User = require('../models/user')

module.exports = {
  authentication: function(req, res, next) {
    try {
      const user = jwt.verifyToken(req.headers.token, process.env.JWT_KEY)
      User.findOne({ email: user.email }).then(result => {
        if (result) {
          req.body.user = result
          req.params.user = result
          next()
        } else {
          throw new Error('User not found')
        }
      })
    } catch (error) {
      console.log('langsung dia masuk sini')

      next(error)
    }
  },

  adminOnly: function(req, res, next) {
    let loginUser = req.body.user
    if (loginUser && loginUser.role === 'admin') {
      next()
    } else {
      next(new Error('Not Authorized'))
    }
  }
}

====error handler==== MIDDLEWARE
const errorHelper = require('../helpers/errorHandling')

module.exports = function(err, req, res, next) {
  //   console.log(err)
  let errorToSend = errorHelper(err)
  // console.log(errorToSend)
  res.status(errorToSend.statusCode).json(errorToSend)
}


====error handling==== HELPER
var nodeError = ["Error","EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]
var mongooseError = ["MongooseError","DisconnectedError","DivergentArrayError","MissingSchemaError","DocumentNotFoundError","MissingSchemaError","ObjectExpectedError","ObjectParameterError","OverwriteModelError","ParallelSaveError","StrictModeError","VersionError"]
var mongooseErrorFromClient = ["CastError","ValidatorError","ValidationError"];
var jwtError = ["TokenExpiredError","JsonWebTokenError","NotBeforeError"]

function nodeErrorMessage(message){
    switch(message){
        case "Token is undefined":{
            return 403;
        }
        case "User not found":{
            return 403;
        }
        case "Not Authorized":{
            return 401;
        }
        case "Email is Invalid!":{
            return 400;
        }
        case "Password is Invalid!":{
            return 400;
        }
        case "Incorrect password for register as admin":{
            return 400;
        }
        case "Item id not found":{
            return 400;
        }
        case "Email or Password is invalid": {
            return 400
        }
        default :{
            return 500;
        }
    }
}

module.exports = function(errorObject){
    // console.log("===ERROR OBJECT===")
    // console.log(errorObject)
    // console.log("===ERROR STACK===")
    // console.log(errorObject.stack);

    let statusCode = 500;  
    let returnObj = {
        error : errorObject
    }
    if(jwtError.includes(errorObject.name)){
        statusCode = 403;
        returnObj.message = "Token is Invalid"
        returnObj.source = "jwt"
    }
    else if(nodeError.includes(errorObject.name)){
        returnObj.error = JSON.parse(JSON.stringify(errorObject, ["message", "arguments", "type", "name"]))
        returnObj.source = "node";
        statusCode = nodeErrorMessage(errorObject.message);
        returnObj.message = errorObject.message;
    }else if(mongooseError.includes(errorObject.name)){
        returnObj.source = "database"
        returnObj.message = "Error from server"
    }else if(mongooseErrorFromClient.includes(errorObject.name)){
        returnObj.source = "database";
        errorObject.message ? returnObj.message = errorObject.message : returnObj.message = "Bad Request"
        statusCode = 400;
    }else{
        returnObj.source = "unknown error";
        returnObj.message = "Something error";
    }
    returnObj.statusCode = statusCode;
    
    return returnObj;


}


===jwt====
const jwt = require('jsonwebtoken')

function generateToken(payload) {
    let token = jwt.sign(payload, process.env.JWT_KEY)
    return token
}

function verifyToken(token) {
    let payload = jwt.verify(token, process.env.JWT_KEY)
    return payload
}

module.exports = {
    generateToken, verifyToken
}

===router index===
const express = require('express')
const router = express.Router()

// router.get('/', )
router.use('/users', require('./users'))
router.use('/products', require('./product'))
router.use('/transactions', require('./transaction'))

module.exports = router

====router user ====
const express = require('express')
const router = express.Router()
const User = require('../controllers/userController')
const auth = require('../middlewares/auth')

/* GET users listing. */
router.post('/register', User.register)
router.post('/login', User.login)
router.get('/', auth.authentication, User.getUser)
router.post('/logout', auth.authentication, User.logout)
module.exports = router


====app====
require('dotenv').config()
const express = require('express')
const cookieParser = require('cookie-parser')
const logger = require('morgan')
const cors = require('cors')
const indexRouter = require('./routes/index')
const errorHandler = require('./middlewares/errorHandler')
const mongoose = require('mongoose')
const app = express()

mongoose.connect(process.env.DB_URI, {
  useNewUrlParser: true,
  useUnifiedTopology: true,
  useCreateIndex: true,
  useFindAndModify: false
})

app.use(cors())
app.use(logger('dev'))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())

app.use('/', indexRouter)
app.use(errorHandler)

module.exports = app

答案 6 :(得分:0)

为什么不剖析裸机最低认证模块?

SweetAuth

轻量级,零配置的用户身份验证模块,不依赖于数据库。

https://www.npmjs.com/package/sweet-auth

很简单:

app.get('/private-page', (req, res) => {

    if (req.user.isAuthorized) {
        // user is logged in! send the requested page
        // you can access req.user.email
    }
    else {
        // user not logged in. redirect to login page
    }
})
相关问题