ExpressJS - 身份验证
身份验证是将提供的凭据与本地操作系统或身份验证服务器中授权用户信息数据库中的凭据进行比较的过程。如果凭据匹配,则该过程完成,并授予用户访问权限。
为了创建身份验证系统,我们需要创建一个注册页面和一个用户密码存储。以下代码为我们创建一个帐户并将其存储在内存中。这只是为了演示;建议始终使用持久存储(数据库或文件)来存储用户信息。
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var multer = require('multer'); var upload = multer(); var session = require('express-session'); var cookieParser = require('cookie-parser'); app.set('view engine', 'pug'); app.set('views','./views'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(upload.array()); app.use(cookieParser()); app.use(session({secret: "Your secret key"})); var Users = []; app.get('/signup', function(req, res){ res.render('signup'); }); app.post('/signup', function(req, res){ if(!req.body.id || !req.body.password){ res.status("400"); res.send("Invalid details!"); } else { Users.filter(function(user){ if(user.id === req.body.id){ res.render('signup', { message: "User Already Exists! Login or choose another user id"}); } }); var newUser = {id: req.body.id, password: req.body.password}; Users.push(newUser); req.session.user = newUser; res.redirect('/protected_page'); } }); app.listen(3000);
现在对于注册表单,创建一个名为signup.jade的新视图。
SIGNUP.JADE
html head title Signup body if(message) h4 #{message} form(action = "/signup" method = "POST") input(name = "id" type = "text" required placeholder = "User ID") input(name = "password" type = "password" required placeholder = "Password") button(type = "Submit") Sign me up!
通过访问 localhost:3000/signup 检查此页面是否加载。
我们已为两个字段设置了必需属性,因此支持 HTML5 的浏览器将不允许我们提交此表单,除非我们同时提供 ID 和密码。如果有人尝试使用 curl 请求注册而没有用户 ID 或密码,则会显示错误。在视图中创建一个名为 protected_page.pug 的新文件,内容如下 −
html head title Protected page body div Hey #{id}, How are you doing today? div Want to log out? div Logout
只有用户刚刚注册或登录后,该页面才可见。现在让我们定义它的路由以及登录和注销的路由 −
var express = require('express'); var app = express(); var bodyParser = require('body-parser'); var multer = require('multer'); var upload = multer(); var session = require('express-session'); var cookieParser = require('cookie-parser'); app.set('view engine', 'pug'); app.set('views','./views'); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(upload.array()); app.use(cookieParser()); app.use(session({secret: "Your secret key"})); var Users = []; app.get('/signup', function(req, res){ res.render('signup'); }); app.post('/signup', function(req, res){ if(!req.body.id || !req.body.password){ res.status("400"); res.send("Invalid details!"); } else { Users.filter(function(user){ if(user.id === req.body.id){ res.render('signup', { message: "User Already Exists! Login or choose another user id"}); } }); var newUser = {id: req.body.id, password: req.body.password}; Users.push(newUser); req.session.user = newUser; res.redirect('/protected_page'); } }); function checkSignIn(req, res){ if(req.session.user){ next(); //If session exists, proceed to page } else { var err = new Error("Not logged in!"); console.log(req.session.user); next(err); //Error, trying to access unauthorized page! } } app.get('/protected_page', checkSignIn, function(req, res){ res.render('protected_page', {id: req.session.user.id}) }); app.get('/login', function(req, res){ res.render('login'); }); app.post('/login', function(req, res){ console.log(Users); if(!req.body.id || !req.body.password){ res.render('login', {message: "Please enter both id and password"}); } else { Users.filter(function(user){ if(user.id === req.body.id && user.password === req.body.password){ req.session.user = user; res.redirect('/protected_page'); } }); res.render('login', {message: "Invalid credentials!"}); } }); app.get('/logout', function(req, res){ req.session.destroy(function(){ console.log("user logged out.") }); res.redirect('/login'); }); app.use('/protected_page', function(err, req, res, next){ console.log(err); //User should be authenticated! Redirect him to log in. res.redirect('/login'); }); app.listen(3000);
我们创建了一个中间件函数 checkSignIn 来检查用户是否已登录。protected_page 使用此函数。要注销用户,我们需要销毁会话。
现在让我们创建登录页面。将视图命名为 login.pug 并输入内容 −
html head title Signup body if(message) h4 #{message} form(action = "/login" method = "POST") input(name = "id" type = "text" required placeholder = "User ID") input(name = "password" type = "password" required placeholder = "Password") button(type = "Submit") Log in
我们的简单身份验证应用程序现已完成;现在让我们测试该应用程序。使用 nodemon index.js 运行应用程序,然后转到 localhost:3000/signup。
输入用户名和密码,然后单击注册。如果详细信息有效/唯一,您将被重定向到 protected_page −
现在退出应用程序。这会将我们重定向到登录页面 −
此路由受到保护,如果未经身份验证的人尝试访问它,他将被重定向到我们的登录页面。这都是关于基本用户身份验证的。我们始终建议使用持久会话系统并使用哈希来传输密码。现在有更好的方法来验证用户身份,即利用 JSON 令牌。