node --- [express] cookie/session 机制与 中间件的使用(路由守卫)

说明

  • 源代码
  • 记忆、遗忘回顾
  • 使用 cookie/session 机制,让 客户端/服务器 的访问变得有状态

cookie 与 session

  • 由于 HTTP 协议的无状态性,当一次连接断开后. 服务器并不会记录用户是否登录. 因此需要引入 cookie/session 机制

cookie

cookie: 浏览器在电脑硬盘中开辟的一块空间,主要供服务器端存储数据

  • cookie 中的数据是以域名的形式进行区分的.

  • cookie 中的数据是有过期时间的,超过时间数据会被浏览器自动删除.

  • cookie 中的数据会随着请求被自动发送到服务器

    1.客户端第一次向服务器端发送请求的时候,是不存在 cookie 的.
    2.服务端验证客户端,会响应一个 cookie 给客户端.
    3.客户端验证通过后,在发送请求会自动带上 cookie


session

session:实际上就是一个对象,存储在服务器端的内存中,在 session 对象中也可以存储多条数据,每一条数据都有一个 sessionid 做为唯一标识.

注意:cookie 在客户端的磁盘中,session 在服务端的内存中


cookie 和 session 的使用(理论)

  1. [client] --> 邮件地址、密码 --> [server]
  2. server 端,对邮箱地址、密码进行验证,若通过则生成 sessionid
  3. [client] <-- sessionid(存储在客户端的 cookie 中) <-- [server]
  4. 客户端再次登录
  5. [client] --> cookie [server]
  6. 服务端,获取 cookie 中的 sessionid,验明身份后,响应数据

实战: cookie 与 session

  • 配置获取POST请求参数
// 配置获取post参数
const bodyParser = require('body-parser')
// extended: false 方法内部使用querystring模块处理请求参数的格式
// extended: true  方法内部使用第三方模块qs处理请求参数的格式
// 拦截所有请求
app.use(bodyParser.urlencoded({ extended: false }))
  • 验证成功后,生产session信息
const User = require('../../model/user')
const session = requier('express-session')
app.use(session({ secret: 'secret key' }))
admin.post('/login', async (req, res) => {const { email, password } = req.bodyconst user = await User.findOne({ email })// 假设登录成功req.session.username = user.username // 此处能用req.session是在app.js中使用app.use方法进行了拦截
})
  • User是使用mongoose的接口创建的集合规则
  • User.findOne(): 通过邮箱再数据库中查找数据
  • req.session.username: 执行后,会在内存中创建
    在这里插入图片描述

中间件的使用

什么是中间件

  • 中间件就是一堆方法
  • 可以接收客户端发来的请求、可以对请求做出响应,也可以将请求继续交给下一个中间件继续处理.
  • 将一个复杂的请求处理逻辑分开处理
  • 也可以将请求到达指定路由前,先进行验证处理: 如用户是否登录

中间件的构成

  • 中间件方法以及请求处理函数
  • 中间件方法: 由Express提供,负责拦截请求,请求处理函数由开发人员提供,负责处理请求.
app.get('请求路径', '处理函数');   // 接收并处理get请求
app.post('请求路径', '处理函数');   // 接收并处理post请求
  • 可以对同一请求设置多个中间件,对同一请求进行多次处理
  • 默认情况下,请求从上到下依次匹配中间件,一旦匹配成功,终止匹配
  • 可以调用next方法将请求的控制权交给下一个中间件,直到遇到结束请求的中间件.
app.get('/request', (req, res, next) =>{req.name = "张三";next();
})
app.get('/request', (req,res) =>{res.send(req.name);
});

app.use的使用

  • 它有2个参数, 第一个参数不写对所有路径的请求进行拦截
  • 若填写了第一个参数,则对该路径下的路由进行拦截
  • 第二个参数是路由处理函数
// 拦截所有路由
app.use((req,res,next)=>{console.log(req.url);next();
})// 拦截 /admin 下的所有路由
app.use('/admin', (req, res, next)=>{console.log(req.url);next()
})

路由守卫

  • 简单的说就是在所有路由前面或者后面,针对特定路径或所有路径的一个特殊的app.use方法.

登录守卫

  • 放在所有的路由前面,即客户端访问第一个经过的函数
// 拦截 -> 路由守卫
app.use('/admin', require('./middleware/loginGuard'))// 其他路由中间件
app.get(...);
app.post(...);
  • loginGuard
module.exports = (req, res, next) => {if (req.url !== '/login') {// 访问的不是登录页面// 判断用户是否登录if (req.session.username) {next()} else {res.redirect('/admin/login')}} else {// 访问的是登录页面next()}
}
  • next: 将执行权,传递给下一个中间件
  • res.redirect: 重定向到路由 /admin/login

错误守卫

  • 放在比较靠后的中间件. 用来收集错误信息
// 其他路由中间件
app.get(...);
app.post(...);// 错误 -> 路由守卫
app.use(require('./middleware/errorGuard.js'))
  • 当其他路由发现错误时(如验证不通过),使用next将执行权往后传递.
  • 传递到最后,有错误守卫对错误信息进行收集.
  • 发现错误并传递错误的代码(部分)如下:
// 比如在更新用户信息的时候,新传递的数据和数据库里面的格式不符合
try {await validateUser(req.body)
} catch (ex) {return next(JSON.stringify({ path: '/admin/user-edit', msg: ex.message }))
}

validateUser: 是验证用户信息的一个函数,验证通过返回true,否则会抛出异常.
catch: 用于捕获异常.
return: 是阻止程序向下执行.
JSON.stringfify: 是因为app.use(param1,param2)中的param2的第一个参数err只接收一个字符串类型.因此需要使用该方法将对象转换成字符串

  • 此时函数的执行权,交给了下一个中间件errorGuard.js
module.exports = (err, req, res, next) => {const result = JSON.parse(err)let params = []for (let attr in result) {if (attr != 'path') {params.push(attr + '=' + result[attr])}}res.redirect(`${result.path}?${params.join('&')}`)
}
  • 它将收集到的参数拼接成get请求的参数部分. 然后重定向

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/250366.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

kprobe原理解析

参考 http://www.cnblogs.com/honpey/p/4575928.html kprobe是linux内核的一个重要特性&#xff0c;是一个轻量级的内核调试工具&#xff0c;同时它又是其他一些更高级的内核调试工具&#xff08;比如perf和systemtap&#xff09;的“基础设施”&#xff0c;4.0版本的内核中&a…

02 数据类型

转载于:https://www.cnblogs.com/theoup/p/9875293.html

css --- [学习笔记]背景图片小结 css三大特性

源代码 参考 1. 行高(line-height) 目标 理解 - 能说出行高和高度三种关系 - 能简单理解为什么行高等于单行文字会垂直居应用 使用行高实现单行文字垂直居中能会测量行高 2. CSS 背景(background) 目标 理解 - 背景的作用css 背景图片和插入图片的区别 应用 通过 css 背景…

(数据科学学习手札30)朴素贝叶斯分类器的原理详解Python与R实现

一、简介 要介绍朴素贝叶斯&#xff08;naive bayes&#xff09;分类器&#xff0c;就不得不先介绍贝叶斯决策论的相关理论&#xff1a; 贝叶斯决策论&#xff08;bayesian decision theory&#xff09;是概率框架下实施决策的基本方法。对分类任务来说&#xff0c;在所有相关概…

【技术累积】【点】【java】【29】MapUtils

内容 是Apache组织下的commons-collections包中的工具类<dependency><groupId>commons-collections</groupId><artifactId>commons-collections</artifactId><version>3.2.1</version></dependency> Map操作相关的&#xff0c…

css --- [读书笔记] 盒模型(边框、内外边距)

说明 源代码学习 盒子模型(css重点) css学习三大重点: css盒子模型、 浮动、 定位 目标: 能说出盒子模型由哪四部分组成: 内容、边框、内外边距能说出内边距的作用,设置不同数值分别代表的意思: 控制内部块级元素和宽框的距离能说出块级盒子居中对齐需要的2个条件能说出外边…

Java 泛型,你了解类型擦除吗?

泛型&#xff0c;一个孤独的守门者。大家可能会有疑问&#xff0c;我为什么叫做泛型是一个守门者。这其实是我个人的看法而已&#xff0c;我的意思是说泛型没有其看起来那么深不可测&#xff0c;它并不神秘与神奇。泛型是 Java 中一个很小巧的概念&#xff0c;但同时也是一个很…

css --- [读书笔记] 浮动(float) 与 清除浮动

说明 源代码学习 1. 浮动 1.1 CSS布局的三种机制 网页布局的核心 — 利用 CSS 来摆放盒子 CSS提供了3种机制来设置盒子的摆放位置: 标准流、浮动和定位. 标准流: 块级元素(div、hr、p、h1~h6、ul、ol、dl、form、table)会独占一行,从上向下顺序排列行内元素(span、a、i、em)…

Shiro身份认证---转

目录1.Shro的概念2.Shiro的简单身份认证实现3.Shiro与spring对身份认证的实现前言&#xff1a; Shiro 可以非常容易的开发出足够好的应用&#xff0c;其不仅可以用在 JavaSE 环境&#xff0c;也可以用在 JavaEE 环境。Shiro 可以帮助我们完成&#xff1a;认证、授权、加密、会话…

模板 Trie树

模板 Trie树 code&#xff1a; #include <iostream> #include <cstdio>using namespace std;const int wx20017;inline int read(){int sum0,f1; char chgetchar();while(ch<0||ch>9){if(ch-)f-1; chgetchar();}while(ch>0&&ch<9){sum(sum<…

css --- [练手小项目]样式小结(字体、颜色的语义 清除浮动的使用)

说明 源代码 1.1 CSS属性书写顺序(重点) 建议遵循以下顺序: 1.布局定位属性: display / position / float / clear / visibility / overflow (建议display第一个写, 毕竟关系到模式) 2.自身属性: width / height / margin / padding / border / background 3.文本属性: co…

《Hive编程指南》14.3 投影变换的实践出错原因分析

自己在学习14.3节投影变换执行SQL语句hive (default)> SELECT TRANSFORM(col1, col2) USING /bin/cut -f1 AS newA, newB FROM a;时出现了这个错误 Ended Job job_local1231989520_0004 with errors Error during job, obtaining debugging information... FAILED: Executi…

链式前向星(转)

转自大佬博客https://blog.csdn.net/ACdreamers/article/details/16902023 我们首先来看一下什么是前向星. 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序, 并记录下以某个点为起点的所有边在数组中的起始位…

javascript --- [FormData的使用] 表单元素转换成表单 对象二进制文件上传

1. FormData的作用 1.1 将Form表单元素,转换成表单对象 在使用Ajax进行表单提交的时候,采用原生的js获取dom,然后添加属性.当表单项很多的时候,代码会很多.不利于后期阅读、维护. 这时,可以使用FormData对象,将HTML中的表单元素转换成表单对象,如下: <!-- 表单对象 -->…

android studio gradle 国内代理

使用阿里云的国内镜像仓库地址&#xff0c;就可以快速的下载需要的文件 修改项目根目录下的文件 build.gradle &#xff1a; buildscript { repositories { maven{ url http://maven.aliyun.com/nexus/content/groups/public/} } } allprojects { …

爬虫—01-爬虫原理与数据抓取

爬虫的更多用途 12306抢票 网站上的头票 短信轰炸关于Python网络爬虫&#xff0c;我们需要学习的有&#xff1a; Python基础语法学习&#xff08;基础知识&#xff09;对HTML页面的内容抓取&#xff08;数据抓取&#xff09;对HTML页面的数据提取&#xff08;数据提取&#xff…

javascript --- [FormData的使用] 文件上传进度条展示 文件上传图片即使预览

1. 准备工作 因为要发送Ajax请求,而Ajax技术的运行需要网站环境,因此其中一个解决方案是,将页面作为网站的静态资源暴露出来,然后通过浏览器进行访问. 1.1 静态资源 使用express将public下面的资源暴露出来在根目录下面新建一个public文件夹和一个app.js文件 // app.js con…

2018年春阅读计划---阅读笔记4

uml图的几大特点&#xff1a;容易掌握 2.面向对象 3.可视化&#xff0c;表达能力强大 4.容易掌握使用 5.与编程语言的关系。用c&#xff0c;java等编程语言可以实现一个系统&#xff0c;支持uml 的一些工具&#xff0c;可以根据uml所建立的系统模型自动产生代码框架。 uml的5类…

TP5之安全机制

防止sql注入 1、查询条件尽量使用数组方式&#xff0c;具体如下&#xff1a; 1 $wheres array(); 2 3 $wheres[account] $account; 4 5 $wheres[password] $password; 6 7 $User->where($wheres)->find(); 2、如果必须使用字符串&#xff0c;建议使用预处理机制&am…

javascript --- [jsonp] script标签的妙用(绕过同源限制)

1. 同源 1.1 什么是同源 协议、域名、端口号相同 1.2 为什么有同源政策 同源政策是为了保护用户信息的安全,放置恶意的网站窃取数据。最初的同源政策是指A网站再客户端设置的Cookie,B网站是不能访问的. 随着互联网的发展,同源政策也越来越严格,在不同源的情况下,其中有一项…