iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Node怎么运用Cookie和Session进行登录验证
  • 261
分享到

Node怎么运用Cookie和Session进行登录验证

2023-07-04 16:07:53 261人浏览 安东尼
摘要

本篇内容主要讲解“node怎么运用Cookie和Session进行登录验证”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node怎么运用Cookie和Session进行登录验证”吧!1️⃣ 定义

本篇内容主要讲解“node怎么运用Cookie和Session进行登录验证”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node怎么运用Cookie和Session进行登录验证”吧!

1️⃣ 定义页面路由

vies目录下新建login.ejs

<!DOCTYPE html><html><head>    <meta charset="UTF-8">    <meta Http-equiv="X-UA-Compatible" content="IE=edge">    <meta name="viewport" content="width=device-width, initial-scale=1.0">    <title>Document</title></head><body>    <h2>登录页面</h2>    <div>用户名:<input type="text" id="username"></div>    <div>密码:<input type="passWord" id="password"></div>    <div><button id="login">登录</button></div>    <script>        const uname = document.getElementById("username");        const pwd = document.getElementById("password");        const login = document.getElementById("login");        login.onclick = () => {            fetch('/api/login', {                method: 'POST',                body: JSON.stringify({                    username: uname.value,                    password: pwd.value                }),                headers: {                    "Content-Type": "application/json"                }            }).then(res => res.json()).then(res => {                // console.log(res);                if (res.ok) {                    location.href = "/"                } else {                    alert("用户名密码不匹配!")                }            })        }    </script></body></html>

注意:页面中请求的接口是POST /api/login请求

routes目录下新建login.js,该文件定义login页面的页面路由:

var express = require("express");var router = express.Router();router.get("/", function (req, res, next) {    res.render("login");});module.exports = router;

app.js中挂载页面路由:

// 引入var loginRouter = require("./routes/login");// 挂载app.use("/login", loginRouter);

启动项目,访问http://localhost:3000/login正常显示:

Node怎么运用Cookie和Session进行登录验证

2️⃣ 定义API接口

services/UserService.js中定义接口的模型(M层):

const UserService = {// .......    // 登录查询    login: (username, password) => {    // 向数据库查询该用户        return UserModel.findOne({ username, password });    },};

controllers/UserController.js中定义接口的控制层(C层):

const UserController = { // ...... // 登录验证    login: async (req, res, next) => {        try {            const { username, password } = req.body;            const data = await UserService.login(username, password);            // console.log(data);            if (data) {                res.send({ ok: 1, msg: "登录成功!", data });            } else {                res.send({ ok: 0, msg: "用户不存在,登录失败!" });            }        } catch (error) {            console.log(error);        }    },};

routes/users.js中定义Api路由:

// 登录校验router.post("/login", UserController.login);

至此登录页面就搭建好了:

Node怎么运用Cookie和Session进行登录验证

3️⃣ 配置session

在上一节Cookie-Session登录验证工作原理的介绍中我们知道:

Node怎么运用Cookie和Session进行登录验证

图一

这个过程显然是比较复杂的,在express中有一个express-session模块可以大大降低我们的工作量,让我们站在巨人的肩膀上开发

下载express-session

npm i express-session

app.js中进行配置:

// 引入express-sessionvar session = require("express-session");// 配置session:需要放在在路由配置的前面app.use(    session({        name: "AilixUserSystem", // cookie名字        secret: "iahsiuhaishia666sasas", // 密钥:服务器生成的session的签名        cookie: {            maxAge: 1000 * 60 * 60, // 过期时间:一个小时过期            secure: false, // 为true时表示只有https协议才能访问cookie        },        resave: true, // 重新设置session后会重新计算过期时间        rolling: true, // 为true时表示:在超时前刷新时cookie会重新计时;为false表示:在超时前无论刷新多少次,都是按照第一次刷新开始计时        saveUninitialized: true, // 为true时表示一开始访问网站就生成cookie,不过生成的这个cookie是无效的,相当于是没有激活的信用卡    }));

配置好后,就会发现浏览器中有一个名为AilixUserSystemcookie

Node怎么运用Cookie和Session进行登录验证

这是因为express-session会自动解析cookie和向前端设置cookie,相当于是图一中的3、6(前半部分:通过SessionId查询到Session ,我们不再需要手动对cookie进行操作。

4️⃣ 权限验证

在登录成功时设置session

// controllers/UserController.js// ....// 登录校验login: async (req, res, next) => {   try {       const { username, password } = req.body;       const data = await UserService.login(username, password);       // console.log(data);       if (data) {           // 设置session:向session对象内添加一个user字段表示当前登录用户           req.session.user = data; // 默认存在内存中,服务器一重启就没了           res.send({ ok: 1, msg: "登录成功!", data });       } else {           res.send({ ok: 0, msg: "用户不存在,登录失败!" });       }   } catch (error) {       console.log(error);   }},

我们向req.session中添加了一个user字段,来保存用户登录的信息,这一步相当于是 图一中的1(SessionId会由express-session模块自动生成)、2

req.session是一个session对象,需要注意的是这个对象虽然存在于req中,但其实不同的人访问系统时他们的req.session是不同的,因为 req.session是根据我们设置的cookie(由express-session模块自动生成的AilixUserSystem )生成的,每一个人访问系统所生成的cookie是独一无二的,所以他们的req.session也是独一无二的。

在收到请求时校验session,在app.js添加以下代码:

// 设置中间件:session过期校验app.use((req, res, next) => {    // 排除login相关的路由和接口    // 这个项目中有两个,一个是/login的页面路由,一个是/api/login的post api路由,这两个路由不能被拦截    if (req.url.includes("login")) {        next();        return;    }    if (req.session.user) {        // session对象内存在user,代表已登录,则放行        // 重新设置一下session,从而使session的过期时间重新计算(在session配置中配置了: resave: true)        // 假如设置的过期时间为1小时,则当我12点调用接口时,session会在1点过期,当我12点半再次调用接口时,session会变成在1点半才会过期        // 如果不重新计算session的过期时间,session则会固定的1小时过期一次,无论这期间你是否进行调用接口等操作        // 重新计算session的过期时间的目的就是为了防止用户正在操作时session过期导致操作中断        req.session.myData = Date.now();        // 放行        next();    } else {        // session对象内不存在user,代表未登录        // 如果当前路由是页面路由,,则重定向到登录页        // 如果当前理由是api接口路由,则返回错误码(因为针对ajax请求的前后端分离的应用请求,后端的重定向不会起作用,需要返回错误码通知前端,让前端自己进行重定向)        req.url.includes("api")            ? res.status(401).send({ msg: "登录过期!", code: 401 })            : res.redirect("/login");    }});

注意:这段代码需要在路由配置的前面。

这段代码中我们通过req.session.myData = Date.now();来修改session对象,从而触发session过期时间的更新(sessionmyData这个属性以及它的值 Date.now()只是我们修改session对象的工具其本身是没有任何意义的),你也可以使用其它方法,只要能将req.session修改即可。

因为我们这个项目是后端渲染模板的项目,并不是前后端分离的项目,所以在配置中间件进行session过期校验拦截路由时需要区分Api路由页面路由

后端在拦截API路由后,向前端返回错误和状态码:

Node怎么运用Cookie和Session进行登录验证

这个时候需要让前端自己对返回结果进行判断从而进行下一步的操作(如回到登录页或显示弹窗提示),该系统中前端是使用javascript内置的fetch来进行请求发送的,通过它来对每一个请求结果进行判断比较麻烦,大家可以自行改用axiOS,在axios的响应拦截器中对返回结果做统一的判断。

5️⃣ 退出登录

向首页(index.ejs)添加一个退出登录的按钮:

<button id="exit">退出登录</button>

为按钮添加点击事件:

const exit = document.getElementById('exit')// 退出登录exit.onclick = () => {  fetch("/api/loGout").then(res => res.json()).then(res => {    if (res.ok) {      location.href = "/login"    }  })}

这里调用了GET /api/logout接口,现在定义一下这个接口,在controllers/UserController.js中定义接口的控制层(C层):

const UserController = { // ......    // 退出登录    logout: async (req, res, next) => {        // destroy方法用来清除cookie,当清除成功后会执行接收的参数(一个后调函数)        req.session.destroy(() => {            res.send({ ok: 1, msg: "退出登录成功!" });        });    },};

routes/users.js中定义Api路由:

// 退出登录router.get("/logout", UserController.logout);

6️⃣ 链接数据库

前面我们通过 req.session.user = data;设置的session默认是存放到内存中的,当后端服务重启时这些session就会被清空,为了解决这一问题我们可以将session存放到数据库中。

安装connect-mongo

npm i connect-mongo

connect-mongo是MongoDB会话存储,用于用typescript编写的连接Express

修改app.js

// 引入connect-mongovar MongoStore = require("connect-mongo");// 配置sessionapp.use(    session({        name: "AilixUserSystem", // cookie名字        secret: "iahsiuhaishia666sasas", // 密钥:服务器生成的session的签名        cookie: {            maxAge: 1000 * 60 * 60, // 过期时间:一个小时过期            secure: false, // 为true时表示只有https协议才能访问cookie        },        resave: true, // 重新设置session后会重新计算过期时间        rolling: true, // 为true时表示:在超时前刷新时cookie会重新计时;为false表示:在超时前无论刷新多少次,都是按照第一次刷新开始计时        saveUninitialized: true, // 为true时表示一开始访问网站就生成cookie,不过生成的这个cookie是无效的,相当于是没有激活的信用卡        store: MongoStore.create({            mongoUrl: "mongoDB://127.0.0.1:27017/usersystem_session", // 表示新建一个usersystem_session数据库用来存放session            ttl: 1000 * 60 * 60, // 过期时间        }), // 存放数据库的配置    }));

到此,相信大家对“Node怎么运用Cookie和Session进行登录验证”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: Node怎么运用Cookie和Session进行登录验证

本文链接: https://www.lsjlt.com/news/346592.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • C++ 生态系统中流行库和框架的贡献指南
    作为 c++++ 开发人员,通过遵循以下步骤即可为流行库和框架做出贡献:选择一个项目并熟悉其代码库。在 issue 跟踪器中寻找适合初学者的问题。创建一个新分支,实现修复并添加测试。提交...
    99+
    2024-05-14
    框架 c++ 流行库 git
  • C++ 生态系统中流行库和框架的社区支持情况
    c++++生态系统中流行库和框架的社区支持情况:boost:活跃的社区提供广泛的文档、教程和讨论区,确保持续的维护和更新。qt:庞大的社区提供丰富的文档、示例和论坛,积极参与开发和维护。...
    99+
    2024-05-14
    生态系统 社区支持 c++ overflow 标准库
  • c++中if elseif使用规则
    c++ 中 if-else if 语句的使用规则为:语法:if (条件1) { // 执行代码块 1} else if (条件 2) { // 执行代码块 2}// ...else ...
    99+
    2024-05-14
    c++
  • c++中的继承怎么写
    继承是一种允许类从现有类派生并访问其成员的强大机制。在 c++ 中,继承类型包括:单继承:一个子类从一个基类继承。多继承:一个子类从多个基类继承。层次继承:多个子类从同一个基类继承。多层...
    99+
    2024-05-14
    c++
  • c++中如何使用类和对象掌握目标
    在 c++ 中创建类和对象:使用 class 关键字定义类,包含数据成员和方法。使用对象名称和类名称创建对象。访问权限包括:公有、受保护和私有。数据成员是类的变量,每个对象拥有自己的副本...
    99+
    2024-05-14
    c++
  • c++中优先级是什么意思
    c++ 中的优先级规则:优先级高的操作符先执行,相同优先级的从左到右执行,括号可改变执行顺序。操作符优先级表包含从最高到最低的优先级列表,其中赋值运算符具有最低优先级。通过了解优先级,可...
    99+
    2024-05-14
    c++
  • c++中a+是什么意思
    c++ 中的 a+ 运算符表示自增运算符,用于将变量递增 1 并将结果存储在同一变量中。语法为 a++,用法包括循环和计数器。它可与后置递增运算符 ++a 交换使用,后者在表达式求值后递...
    99+
    2024-05-14
    c++
  • c++中a.b什么意思
    c++kquote>“a.b”表示对象“a”的成员“b”,用于访问对象成员,可用“对象名.成员名”的语法。它还可以用于访问嵌套成员,如“对象名.嵌套成员名.成员名”的语法。 c++...
    99+
    2024-05-14
    c++
  • C++ 并发编程库的优缺点
    c++++ 提供了多种并发编程库,满足不同场景下的需求。线程库 (std::thread) 易于使用但开销大;异步库 (std::async) 可异步执行任务,但 api 复杂;协程库 ...
    99+
    2024-05-14
    c++ 并发编程
  • 如何在 Golang 中备份数据库?
    在 golang 中备份数据库对于保护数据至关重要。可以使用标准库中的 database/sql 包,或第三方包如 github.com/go-sql-driver/mysql。具体步骤...
    99+
    2024-05-14
    golang 数据库备份 mysql git 标准库
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作