一个基础的登录注册Node.js应用,要不要来看看?
今天我们来尝试一个对新手来说比较有挑战的demo,实现一个用户注册登录登出的项目,来吧~
一、准备工作
必要条件:已经安装好了node环境和Mongo数据库,并且启动Mongo数据库
具体步骤: 1、在全局安装express构造器
2、新建文件夹,cd到该文件夹,用express的构造器快速搭建一个express骨架,取名为project
3、cd到project项目目录,安装依赖包
4、因为expree构造器搭建的express初始项目都是为3000端口,而在实际项目开发的时候,3000端口往往被你不小心占用了,并且忘记关闭端口,所以我们修改初始项目中的默认端口,编译器打开project项目,找到bin目录下的www.js文件,将"var port = normalizePort(process.env.PORT || ‘3000’);”中的3000,换成3008~
5、安装我们下面要用到的两个插件express-session和mongoose
1 npm i express-session mongoose -s
6、在project根目录下,命令行输入npm start启动express项目
7、浏览器输入 http://localhost:3008/ ,如果出现这个,那么恭喜你第一步准备工作已经完成
二、路由和视图布局
这里我先简单地将整个项目的视图和路由大概地搭建起来,循序渐进嘛,满满来~
视图 1、在views中修改index.ejs为:
1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html> <html> <head> <title>index</title> <link rel='stylesheet' href='/ stylesheets/style.css' /> </head> <body> <h1>This is Index Page</h1> <a href="/login">Login Page</a> <a href="/register">Register Page</a> </body> </html>
为啥我们这里会有两个href超链接呢,因为方便多个页面跳转
2、在views中新建登录页面 login.ejs,代码为:
1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html> <html > <head > <title > index</title > <link rel ='stylesheet' href ='/stylesheets/style.css' /> </head > <body > <h1 > This is Login Page</h1 > <a href ="/" > Index Page</a > <a href ="/register" > Register Page</a > </body > </html >
3、在views中新建注册页面 register.ejs,代码为:
1 2 3 4 5 6 7 8 9 10 11 12 <!DOCTYPE html> <html > <head > <title > index</title > <link rel ='stylesheet' href ='/stylesheets/style.css' /> </head > <body > <h1 > This is Register Page</h1 > <a href ="/" > Index Page</a > <a href ="/login" > Login Page</a > </body > </html >
路由 1、修改routes文件夹中的index.js为:
1 2 3 4 5 6 7 8 9 var express = require ('express' );var router = express.Router();router.get('/' , function (req, res, next ) { res.render('index' ); }); module .exports = router;
2、在routes文件夹中新建login.js,输入代码:
1 2 3 4 5 6 7 8 9 10 11 12 var express = require ('express' );var router = express.Router();router.get('/' , function (req, res, next ) { res.render('login' ); }); module .exports = router;
3、在routes文件夹中新建register.js,输入代码:
1 2 3 4 5 6 7 8 9 10 11 12 var express = require ('express' );var router = express.Router();router.get('/' , function (req, res, next ) { res.render('register' ); }); module .exports = router;
4、在app.js中引入路由:
将以下代码:
1 2 var index = require ('./routes/index' );var users = require ('./routes/users' );
修改为:
1 2 3 4 var index = require ('./routes/index' );var users = require ('./routes/users' );var login = require ('./routes/login' );var register = require ('./routes/register' );
5、在app.js中设置路由:
1 2 app.use('/' , index); app.use('/users' , users);
1 2 3 4 app.use('/' , index); app.use('/users' , users); app.use('/login' ,login); app.use('/register' ,register);
6、路由配置完成,其实在4和5步中我们添加的代码如下所示:
7、npm start运行项目:
三、实现登录与注册 1、session会话与cookie 我们要实现登录登出,session和cookie是少不了的,它在这个项目中的用处就是当用户已经登录后,在一定时间范围里不必再次输入账号密码,关于session和cookie详细知识,小伙伴们可以查看这篇文章:cookie 和session 的区别详解
在express中使用session,我们一般用express-session这个中间件
1、在app.js中引入中间件
1 var session = require ('express-session' );
2、在app.js中设置session与cookie
1 2 3 4 5 6 7 app.use(session({ secret: 'nice_to_meet_you' , cookie: { maxAge: 15 *60 *1000 , secure: false } }));
{secret : …}用于签名 session id,为啥要做个签名?因为要防止存在客户端浏览器cookie 下的 session id 被恶意篡改。
{cookie:{maxAge:…, secure : false}}用来配置存入 cookie 中的 session id。maxAge表示有效期多久单位为 ms,以及允许http请求条件下也写入 cookie,若 secure 为 true,则用 http访问页面,session id 将不被写入 cookie,https反之。 4、设置完session和cookie,我们现在app.js中代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 var express = require ('express' );var path = require ('path' );var favicon = require ('serve-favicon' );var logger = require ('morgan' );var cookieParser = require ('cookie-parser' );var bodyParser = require ('body-parser' );var session = require ('express-session' );var index = require ('./routes/index' );var users = require ('./routes/users' );var login = require ('./routes/login' );var register = require ('./routes/register' );var app = express();app.set('views' , path.join(__dirname, 'views' )); app.set('view engine' , 'ejs' ); app.use(logger('dev' )); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended : false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public' ))); app.use(session({ secret: 'nice_to_meet_you' , cookie: { maxAge: 15 *60 *1000 , secure: false } })); app.use('/' , index); app.use('/users' , users); app.use('/login' ,login); app.use('/register' ,register); app.use(function (req, res, next ) { var err = new Error ('Not Found' ); err.status = 404 ; next(err); }); app.use(function (err, req, res, next ) { res.locals.message = err.message; res.locals.error = req.app.get('env' ) === 'development' ? err : {}; res.status(err.status || 500 ); res.render('error' ); }); module .exports = app;
2、主页设置 上一步我们设置好了session和cookie,那我们在主页怎么体现用户是登录状态还是未登录状态呢?
1、修改routes中的index.js为:
1 2 3 4 5 6 7 8 9 10 11 var express = require ('express' );var router = express.Router();router.get('/' , function (req, res, next ) { var user = req.session.user; res.render('index' ,{user :user}); }); module .exports = router;
2、修改views中index.ejs为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <!DOCTYPE html> <html> <head> <title>index</title> <link rel='stylesheet' href='/ stylesheets/style.css' /> </head> <body> <h1>This is Index Page</h1> <% if(user && user.username) { %> <p><%= user.username %>你好,欢迎来到Index</p> <a href="/logout">退出</a> <% }else{ %> <p>您还没有登陆,请登陆之后再操作</p> <a href="/login">登陆</a> <a href="/register">注册</a> <% } %> </body> </html>
index.ejs分析从index.js传过来的user,若有user则显示用户已经登录,若user为空,显示未登陆
3、重新启动npm start,查看index页面
3、实现登录
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 var express = require ('express' );var router = express.Router();var mongoose = require ('mongoose' );router.route('/' ) .get(function (req, res, next ) { res.render('login' ); }) .post(function (req, res, next ) { var username = req.body.username; var password = req.body.password; if (!username || !password){ res.send('<p>用户名或者密码不能为空</p>' ); return ; } var db = mongoose.createConnection('mongodb://localhost:27017/mydb' ); var User = db.model('user' , new mongoose.Schema({ username: String , password: String })); User.findOne({username : username}, 'password' , function (err, data, affectNums ) { if (!data){ res.send('<p>用户不存在</p>' ) return ; } if (data.password === password){ req.session.user = {username : username}; res.redirect('/' ); return ; } res.send('<p>用户名或者密码不正确</p>' ) }) }); module .exports = router;
代码解读:
1 var mongoose = require ('mongoose' );
1 2 3 .get(function (req, res, next ) { res.render('login' ); })
用户填写表单,提交POST的form表单数据,获取username和password数据
1 2 3 4 5 6 7 8 .post(function (req, res, next ) { var username = req.body.username; var password = req.body.password; if (!username || !password){ res.send('<p>用户名或者密码不能为空</p>' ); return ; }
连接数据库,将表单中的username和数据库中的username匹配,并且验证password是否一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var db = mongoose.createConnection('mongodb://localhost:27017/mydb' );var User = db.model('user' , new mongoose.Schema({ username: String , password: String })); User.findOne({username : username}, 'password' , function (err, data, affectNums ) { if (!data){ res.send('<p>用户不存在</p>' ) return ; } if (data.password === password){ req.session.user = {username : username}; res.redirect('/' ); return ; } res.send('<p>用户名或者密码不正确</p>' )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <!DOCTYPE html> <html> <head> <title>index</title> <link rel='stylesheet' href='/ stylesheets/style.css' /> </head> <body> <h1>This is Login Page</h1> <form action="/login" method="post"> <label><span>Account:</span><input type="text" name="username"></label> <label><span>Password:</span><input type="password" name="password"></label> <input type="submit" value="Login" > </form> <a href="/register">还没账号 ?</a> </body> </html>
登录的逻辑代码完成啦,现在重新启动项目,查看login页面:
4、实现注册
同样修改routes中的register.js为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 var express = require ('express' );var router = express.Router();var mongoose = require ('mongoose' );router.route('/' ) .get(function (req, res, next ) { res.render('register' ); }) .post(function (req, res, next ) { var username = req.body.username, password = req.body.password, passwordComfirm = req.body['password-confirm' ], userData = {username : username, password : password}; if (username == '' || password == '' ){ res.json({ 'message' :'Password or Account can not be null' }); return ; } if (password !== passwordComfirm){ res.json({ 'message' :'Password and confirm password do not match' }); return ; } var db = mongoose.createConnection('mongodb://localhost:27017/mydb' ); var Schema = new mongoose.Schema({ username: String , password: String }); var User = db.model('user' ,Schema); User.findOne({username : username},function (err, data ) { if (err){ res.send(err); } if (data){ res.send('<p>Account already exists</p>' ); return ; } User.create(userData,function (err, data, affectNums ) { if (err){ res.json({ message: err }); return ; } if (affectNums == 0 ){ res.send('<p> Register Error </p>' ); return ; } req.session.user = {username : username}; res.redirect('/' ); }); }) }); module .exports = router;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 <!DOCTYPE html> <html > <head > <title > index</title > <link rel ='stylesheet' href ='/stylesheets/style.css' /> </head > <body > <h1 > This is Login Page</h1 > <form action ="/register" method ="post" id ="reg-form" > <label > <span > 用户名:</span > <input type ="text" name ="username" > </label > <label > <span > 密码:</span > <input type ="password" name ="password" > </label > <label > <span > 确认密码:</span > <input type ="password" name ="password-confirm" > </label > <input type ="submit" value ="注册" > </form > <a href ="/login" > 已有账号?</a > <script > (function (g, undefined ) { var form = document .querySelector('#reg-form' ), username = document .querySelector('input[name=username]' ), password = document .querySelector('input[name=password]' ), rePassword = document .querySelector('input[name=password-confirm]' ); form.addEventListener('submit' , function (e ) { e = e || event; e.preventDefault(); if (username.value == "" || password.value == "" ){ alert('用户名或者密码不能为空' ); return false ; } if (password.value == '' ){ alert('确认密码不能为空' ); return false ; } if (password.value !== rePassword.value ){ alert('两次密码输入不一致' ); return false ; } this .submit(); }, false ) })(this ); </script > </body > </html >
到这里我们已经完成了注册和登录,兴奋吧~,别忘了我们还有登出功能没实现哦
5、实现登出 1、我们在routes中新建logout.js。输入代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 var express = require ('express' );var router = express.Router();router.get('/' ,function (req, res, next ) { if (req.session.user){ delete req.session.user; } res.redirect('/' ); return ; }); module .exports = router;
2、回到app.js中向上面那样设置路由 添加代码:
1 2 var logout = require ('./routes/logout' );app.use('/logout' ,logout);
如图:
总结
这个小demo中我们学会了如何设置路由、session与cookie的使用、mongo数据库读写、ejs的基本使用,收获还是不错的~
作为新手入门,代码写到到这里差不多了。当然在实际业务中,登录注册远比现在复杂,验证码也是必须的,折旧等着小伙伴们自己去探索吧~
代码已经放入GitHub中,传送门: Express + EJS + Mongo 实现一个用户注册登录登出
如果你觉得对你有帮助,给个star鼓励啦~
nice to meet you~