IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 网络协议 -> 鉴权之cookie、session、JWT -> 正文阅读

[网络协议]鉴权之cookie、session、JWT

鉴权:判断某用户是否有权访问服务器上的资源。

  • 用户中心这个页面需要用户登录之后才能访问;

  • 某个接口需要token才能访问;

http是无状态的:

早期的web只需要提供信息给访问者就行了,不需要记录状态。浏览器和服务器不能凭借HTTP协议的来辨别请求的上下文。?(服务器不能分辨浏览器发出的请求是不是之前已经请求过。 )

鉴权基本实现思路:

身份信息保存在服务器。(办理消费卡,顾客来了报卡号,在系统上查询)

身份信息保存在客户端。(办理消费卡,顾客来了直接在卡上盖戳)

1.cookie基本介绍:

  • cookie是服务器将数据持久化(保存)存储到客户端(浏览器)的一种技术。

  • cookie是键值对格式的字符串

  • 可以通过浏览器查看某个网站的cookie

1.1cookie的作用:

  • 本地存储。临时少量数据的存储;

  • 由于在向浏览器请求时会自动携带cookie,所以可以用它来做权限验证。

?

1.2cookie鉴权解决方案:

用户登录成功,服务器设置cookie

用户下次请求都会自动带上cookie,服务器解析cookie,判断是否登录

用户退出,服务器删除cookie?

const express = require('express')
const app = express()
app.use(express.static('public'))
app.use(express.urlencoded())

app.post('/login',(req,res)=>{
     // res.setHeader('Access-Control-Allow-Origin', '*')
    // 如何接收 application/json 的数据?
    console.log('接收到的数据是', req.body)
    const {name, password} = req.body
    if( name === 'admin' && password === '123456') {
        // 设置单个cookie
        res.setHeader('set-cookie', 'islogin=yes');
        res.json({msg:'登录成功'})
    } else {
        res.json({msg:'登录失败'})
    }
})

app.get('/testcookie',(req,res) => {
    res.send('/testcookie')
})

app.get('/quit', (req, res) => {
  res.send('删除cookie')
})

app.listen(3000, ()=>{
    console.log(3000);
})

1.2验收效果:

点击页面上的登录,在开发者工具中,观察

  • 检测本次响应是否有set-cookie头。

  • 检测application下cookie中是否有值。

?本地设置cookie成功之后,客户端浏览器向服务器发请求时 ,会自动在请求中自动携带cookie,它被保存在req.headers.cookie中。

1.3在服务器端获取cookie:

?先安装npm install cookie-parser

//先安装npm install cookie-parser

//使用
var cookieParser = require('cookie-parser');
app.use(cookieParser());

//调用,修改后端代码
app.get('/testcookie',(req,res) => {
    console.log('请求携带的cookie是', req.cookies)
    res.json({msg: '测试cookie',data: req.cookies})
})

1.4在服务器端删除cookie:

//express框架提供了一个删除方法。从服务器端删除:
app.get('/quit', (req, res) => {
  res.clearCookie('name');
  res.clearCookie('isLogin');
  res.redirect('/login.html');
});

2.cookie基本介绍:

2.1session鉴权的工作原理:

session 从字面上讲,就是会话。它的工作原理是:

  1. 用户登录成功时,服务器端会生成一个sessionid,并通过set-cookie将生成的sessionid返回给客户端

  2. 客户端收到sessionid会将它保存在cookie中,当客户端再次访问服务端时会带上这个sessionid

  3. 当服务端再次接收到来自客户端的请求时,会先去检查是否存在sessionid,不存在就新建一个sessionid重复1,2的流程,如果存在就去遍历服务端的session文件,找到与这个sessionid相对应的文件,文件中的键值便是sessionid,值为当前用户的一些信息

    通过cookie回传给浏览器的是session编号;真正的数据在服务器端。 ?

?2.2session解决方案

在express框架下, 我们可以通过安装 express-session 包来实现session的功能。

//1. 引入session包
const session = require('express-session');
const app = express();

//2. 配置项
let conf = {
  secret: '123456', //加密字符串。 使用该字符串来加密session数据,自定义
  resave: false, //强制保存session即使它并没有变化
  saveUninitialized: false //强制将未初始化的session存储。当新建了一个session且未
  //设定属性或值时,它就处于未初始化状态。
};

//3. 使用express-session
app.use(session(conf));

在服务器端设置session(req.session.属性名 = 属性值 )

app.post('/login', (req, res) => {
 		// 登录成功
    // 保存数据到session
	  req.session.isLogin = true;
    req.session.name = req.body.username;
    res.end()
}

服务器端获取session(req.session.属性名 )

服务端删除session(req.session.destroy() )

app.get('/quit', (req, res) => {
    req.session.destroy();
}

3.cookie和session的比较

cookie原理:

  • 从服务器端向客户端浏览器留下信息设置响应头:set-cookie

  • 浏览器每次访问服务器时都带上这些信息(自动携带cookie是浏览器的特点);

session原理:

  • 服务器端会为每个用户(浏览器)各自保存一个session(文件)。当服务器保存session之后,会以cookie的形式告诉浏览器,你的session编号是哪一个。它把session号返回给了浏览器,而把真实的数据保存在服务器。

  • 下次再来访问服务器的时候,浏览器就会带着它自己的session号去访问,服务器根据session号就可以找到对应的session了。

cookie:优点是节省服务器空间,缺点不安全。不要保存敏感信息。

session:优点是安全,缺点需要服务器空间(服务器重启,则数据丢失), 是一种最常见的解决方案。

4.JWT(json web token) 基本介绍

token的意思是“令牌”,是服务端生成的一串字符串,作为客户端进行请求的一个标识。

JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。

{
"姓名": "张三",
"角色": "管理员",
"到期时间": "2022年7月11日0点0分"
}

以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。 当然,为了防止用户篡改数据,服务器在生成这个对象的时候,会给他加密一下,就是我们看到的一个长长的字符串。

出现解决的问题是:跨域认证解决方案

基本步骤:

  1. 使用第三方模块 jsonwebtoken 创建token字符串,在项目中下载安装 npm i jsonwebtoken

  2. 加载模块 const jwt = require('jsonwebtoken');

  3. 在用户登陆成功之后,调用 jwt.sign() 方法创建token, 它有如下4个参数:

  • 参数1:必填,对象形式;希望在token中保存的数据

  • 参数2:必填,字符串形式;加密的钥匙;后续验证token的时候,还需要使用

  • 参数3:可选,对象形式;配置项,比如可以配置token的有效期

  • 参数4:可选,函数形式;生成token之后的回调

  • 生成的token前面,必须拼接 Bearer 这个字符串。

    const express = require('express')
    const multer = require('multer')
    const cors = require('cors')
    const app = express();
    app.use(cors({origin:true,credentials:true}))
    const jwt = require('jsonwebtoken');
    app.use(express.urlencoded())
    
    app.post('/login',(req,res)=>{
        console.log('接收到的数据是', req.body)
        const {name, password} = req.body
        if(password === '123456') {
            // 调用生成 token 的方法
            const tokenStr = jwt.sign({name: name }, 'heima61', { expiresIn: 5 });
            const token = 'Bearer ' + tokenStr
            res.json({msg:'登录成功', token})
        } else {
            res.json({msg:'登录失败'})
        }
    })
    
    app.get('/test',(req,res) => {
        res.json({msg: '测试tokenOk'})
    })
    
    app.listen(3000, ()=>{
        console.log(3000);
    })

    浏览器端:保存后端回传的token(保存在localStorage )

    $('#btn_login').click(function(){
      $.ajax({
        type:'post',
        url:'http://localhost:3000/login',
        data:{name:$('#username').val(),password:$('#password').val()},
        success(res){
          console.log(res);
    +      localStorage.setItem('token', res.token)
        }
      })
    })

    浏览器端:发请求时手动携带token(必须放置在Authorization中 )

    $('#btn_testToken').click(function(){
      $.ajax({
        type:'get',
        url:'http://localhost:3000/test',
        headers: {
    +      Authorization: localStorage.getItem('token'),
        },
        success(res){
          console.log(res);
        }
      })
    })

    服务器端:实现token认证(选择使用 express-jwt 第三方模块进行身份认证。从模块名可以看出,该模块是专门配合express使用的。 )

    const expressJwt = require('express-jwt');
    // app.use(jwt().unless());
    // jwt() 用于解析token,并将 token 中保存的数据 赋值给 req.user
    // unless() 约定某个接口不需要身份认证
    app.use(expressJwt({
      secret: 'heima61', // 生成token时的 钥匙,必须统一
      algorithms: ['HS256'] // 必填,加密算法,无需了解
    }).unless({
      path: ['/login'] // 除了个接口,其他都需要认证
    }));

    上述代码完成后,当一个接口请求到了服务器后,它会自动验证请求头中的 Authorization 字段了,并且会自动完成:

    • 如果没有问题

      1. 将token中保存的 数据 赋值给 req.user

      2. next()。

    • 如果有问题,则抛出错误 next(错误信息)?

补充中间件技术-统一处理错误?(在所有的路由最后,加入错误处理中间件,来提示token方面的错误。 )

app.use((err, req, res, next) => {
  if (err.name === 'UnauthorizedError') {
    // res.status(401).send('invalid token...');
    res.status(401).send({ status: 1, message: '身份认证失败!' });
  }
});

  网络协议 最新文章
使用Easyswoole 搭建简单的Websoket服务
常见的数据通信方式有哪些?
Openssl 1024bit RSA算法---公私钥获取和处
HTTPS协议的密钥交换流程
《小白WEB安全入门》03. 漏洞篇
HttpRunner4.x 安装与使用
2021-07-04
手写RPC学习笔记
K8S高可用版本部署
mySQL计算IP地址范围
上一篇文章      下一篇文章      查看所有文章
加:2021-09-27 14:27:29  更:2021-09-27 14:27:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 1:45:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码