Nodejs学习笔记②

写在前面

这次做一个小小的登陆&注销登陆功能练习下所学的知识,并扩充些新知识。

image.png
image.png
image.png

目录

  1. 新建 login 项目
  2. 下载&导入Bootstrap、jQuery
  3. 业务需求实现

新建 login 项目

express -e login //新建 login 项目,-e 指使用 Ejs 模版引擎
cd login //切换到 login 目录
npm i //安装项目依赖
npm start //启动项目,跑起来看看

下载&导入Bootstrap

Bootstrap下载传送门
jQuery下载传送门
bootstrap.min.js jquery-3.2.1.min.jsbootstrap.min.css分别复制到 public 下对应的文件夹

image.png

业务需求实现

分析

访问路径:/,展示页面:index.ejs,不需要登陆,可以直接访问
访问路径:/login,展示页面:login.ejs,登陆页面,输入正确的用户名密码,跳转到 home.ejs
访问路径:/home,页面:home.ejs,用户登陆后才可以访问
访问路径:/logout,页面:home.ejs,注销登陆后回到 index.ejs

先写UI页面
  • 在 views 文件夹下新建文件 header.ejs 和 footer.ejs
<!--header.ejs-->
<!DOCTYPE html>
<html>
  <head>
    <title><%= title %></title>
    <link rel='stylesheet' href='/stylesheets/bootstrap.min.css' />
  </head>
  <body class="container">
<!--footer.ejs-->
<script src="/javascripts/jquery-3.2.1.min.js"></script>
<script src="/javascripts/bootstrap.min.js"></script>
  </body>
</html>
  • 写 index.ejs
<!--index.ejs-->
<% include header.ejs %>
  <h1><%= title %></h1>
  <p>Welcome to <%= title %></p>
  <a class="btn btn-default" href="/login" role="button">登录</a>
<% include footer.ejs %>
  • 写 login.ejs
<!--login.ejs-->
<% include header.ejs %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<form class="form-inline" method="POST">
    <div class="form-group">
        <label class="sr-only" for="username">用户名</label>
        <input type="text" class="form-control" id="username" placeholder="username" name="username">
    </div>
    <div class="form-group">
        <label class="sr-only" for="password">password</label>
        <input type="password" class="form-control" id="password" placeholder="password" name="password">
    </div>
    <button type="submit" class="btn btn-default">登陆</button>
</form>
<% include footer.ejs %>
  • 写 home.ejs
<!--home.ejs-->
<% include header.ejs %>
<h1><%= title %></h1>
<p>登陆成功:<%= user.username %></p>
<a class="btn btn-default" href="/logout" role="button">注销登录</a>
<% include footer.ejs %>
写MCV中的c,controller

在 routes 下新建 controller.js 文件,并增加如下方法

// controller.js
exports.index = function (req, res) {
    res.render('index', { title: '登陆&注销登陆实践' })
}
exports.login = function (req, res) {
    res.render('login', { title: '登陆页面' })
}
exports.doLogin = function (req, res) {
    var user = {
        username: 'admin',
        password: 'admin'
    }
    if (req.body.username === user.username && req.body.password === user.password) {
        res.redirect('/home')
    }
    res.redirect('/login')

}
exports.logout = function (req, res) {
    res.redirect('/')
}
exports.home = function (req, res) {
    var user = {
        username: 'admin',
        password: 'admin'
    }
    res.render('home', { title: '主页面', user: user })
}
在 app.js 中添加路由
// app.use('/', index);
// app.use('/users', users);

var controller = require('./routes/controller')
app.get('/', controller.index)
app.get('/login', controller.login)
app.post('/login', controller.doLogin)
app.get('/logout', controller.logout)
app.get('/home', controller.home)

到这里半成品已经ok了,可以构建项目试试看了~

加入 Session 再完善下

安装 express-session 依赖库
npm install express-session //在工程目录下执行
设置 session
//在 app.js 中设置session
var session = require('express-session')
app.use(session({
  secret: 'login&logout',
  cookie: { maxAge: 900000 },
  resave: false,
  saveUninitialized: false
}));

//注意要写在路由的前面,app.js 有顺序要求
app.use(function (req, res, next) {
  res.locals.user = req.session.user;

  var err = req.session.error;
  delete req.session.error;
  res.locals.message = '';

  //用于错误提示
  if (err) res.locals.message = '<div class="alert alert-danger" role="alert">' + err + '</div>';

  next();
})

// app.use('/', index);
// app.use('/users', users);
修改下 controller.js 中的方法
exports.doLogin = function (req, res) {
    var user = {
        username: 'admin',
        password: 'admin'
    }
    if (req.body.username === user.username && req.body.password === user.password) {
        req.session.user = user;
        res.redirect('/home')
    }
    res.redirect('/login')
}
exports.logout = function (req, res) {
    req.session.user = null;
    res.redirect('/')
}
exports.home = function (req, res) {
    res.render('home', { title: '主页面'})
}
增加登陆失败提示

分别修改 login.ejs 和 controller.js 的 doLogin 方法

<!--login.ejs-->
<% include header.ejs %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<form class="form-inline" method="POST">
    <%- message %> <!--增加错误提示-->
    <div class="form-group">
        <label class="sr-only" for="username">用户名</label>
        <input type="text" class="form-control" id="username" placeholder="username" name="username">
    </div>
    <div class="form-group">
        <label class="sr-only" for="password">password</label>
        <input type="password" class="form-control" id="password" placeholder="password" name="password">
    </div>
    <button type="submit" class="btn btn-default">登陆</button>
</form>
<% include footer.ejs %>
exports.doLogin = function (req, res) {
    var user = {
        username: 'admin',
        password: 'admin'
    }
    if (req.body.username === user.username && req.body.password === user.password) {
        req.session.user = user;
        res.redirect('/home')
    }else{
        req.session.error = "用户名或密码错误"
        res.redirect('/login')
    }
}

输错误的账号,看下如何

image.png
页面访问控制

在 app.js 中加两个方法

function needAuth(req, res, next) {
  if (!req.session.user) {
    req.session.error = '请先登录'
    res.redirect('/login')
  }
  next();
}

function hasAuth(req, res, next) {
  if (req.session.user) {
    res.redirect('/home')
  }
  next();
}

并修改一下路由

app.all('/login', hasAuth) //all 方法拦截所有请求
app.get('/login', controller.login)
app.post('/login', controller.doLogin)

app.get('/logout', needAuth)
app.get('/logout', controller.logout)

app.get('/home', needAuth)
app.get('/home', controller.home)

到此,这个小练习就完成了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • 搭建开发环境并模拟交互数据 一、实验说明 下述介绍为实验楼默认环境,如果您使用的是定制环境,请修改成您自己的环境介...
    玄月府的小妖在debug阅读 2,106评论 0 15
  • 22年12月更新:个人网站关停,如果仍旧对旧教程有兴趣参考 Github 的markdown内容[https://...
    tangyefei阅读 35,159评论 22 257
  • URL的全称是Uniform Resource Locator(统一资源定位符) URL就是资源在互联网上的地址、...
    SessionSinGod阅读 286评论 0 0
  • 好的婚姻不是相濡以沫。如果湖干了,任何两条鱼为了活命都会相濡以沫。 好多的婚姻是湖干了,你领我找到新的湖,我们一起...
    桥段姐阅读 386评论 6 4