当前位置: 首页 > news >正文

Node学习-第六章-express中间件与RESful API接口规范(下)

express 学习

目录

    • express 学习
      • 工具模块-utils文件夹
      • 业务处理模块- controlled文件夹
      • JWT

工具模块-utils文件夹

  1. mod5.js
    md5 加密方式, 使用的是node内置中间件,crypto。
    node内置 crypto模块提供加密功能,其中包括一组用于OpenSSL的散列、HMAC、加密、解密、签名和验证功能的包装器。
    md5加密优化:
    1. 明文加入前缀 实现加密增强
    2. 明文需要复杂

createHash()方法用于创建Hmac实例。HMAC对象不能直接使用new关键字创建。

HMAC是密钥相关的哈希运算消息认证码(Hash-based Message Authentication Code)的缩写

使用hmac.update()计算所有传递数据的HMAC摘要。编码可以是’hex’、‘latin
1’或’base64’。如果提供了编码,则返回字符串;否则返回Buffer;

const crypto = require('crypto'); 
var d = crypto.createHash('md5').update('by'+'121').digest('hex');
console.log('d', d);
module.exports = (str) => {return  crypto.createHash('md5').update('by'+str).digest('hex');
}

express 使用md5加密的信息, 调取时是否需要解密 ?
在使用MD5加密存储用户密码的Express应用中,‌调取时不需要解密。‌
MD5是一种不可逆的加密算法,‌意味着一旦数据被MD5加密,‌就无法直接解密还原成原始数据。‌在Express框架中,‌如果用户密码是通过MD5加密后存储在数据库中的,‌那么在后续的调取过程中,‌不需要进行解密操作。‌这是因为MD5加密的特性决定了它只能用于单向验证,‌即通过输入明文密码与数据库中存储的加密密码进行比对,‌来验证用户输入的密码是否正确。‌

  1. jwt.js
    使用第三方包jsonwebtoken。
    访问官网: jsonwebtoken,并且找到你当前项目语言支持的版本。
$ npm install jsonwebtoken

使用说明:

  1. jwt.sign(payload,secretOrPrivateKey,[options,callback])
    返回值说明:
    (异步调用)如果提供了回调,则使用err或JWT调用回调。
    (同步调用)以字符串形式返回JsonWebToken
    参数说明:
    1.payload可以是一个对象文字,缓冲区或字符串表示有效的JSON。
    2.secretOrPrivateKey是字符串(utf-8编码)、缓冲区、对象或KeyObject,其中包含HMAC算法或PEM的秘密 RSA和ECDSA的加密私钥。
    3.options 配置项,常用配置项,expiresIn 过期时间 120,“2 days”,“10h”,“7d”。(“120"等于"120ms”)algorithm 指定加密算法,默认HMAC SHA256。
  2. jwt.verify(token,secretOrPublicKey,[options,callback])
    返回值说明:
    (异步调用)如果提供了回调,则函数异步操作。如果签名有效并且可选的过期、受众或颁发者有效,则使用解码的有效负载调用回调。如果没有,它将被调用并返回错误。
    (同步调用)如果没有提供回调函数,则函数同步动作。如果签名有效并且可选的过期、访问者或颁发者有效,则返回解码的有效负载。如果没有,它将抛出错误。
    参数说明:
    1.token是JsonWebToken字符串
    2.secretOrPublicKey是一个字符串(utf-8编码)、缓冲区或KeyObject,其中包含HMAC算法的秘密或PEM RSA和ECDSA的加密公钥。
    3.optio配置项
    受众 audience如果你想检查观众(aud),在这里提供一个值。可以针对字符串、正则表达式或字符串和/或正则表达式的列表来检查受众,
    签发人 issuer(可选):iss字段的有效值字符串或字符串数组。
  3. util.promisify()
    Nodejs 8 有一个新的工具函数 util.promisify()。他将一个接收回调函数参数的函数转换成一个返回Promise的函数。
const { error } = require('console');
const jwt = require('jsonwebtoken');
// var token = jwt.sign({fool: 'hellow'}, '555')
// console.log(token)
// const jmtoken =  jwt.verify('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmb29sIjoiaGVsbG93IiwiaWF0IjoxNzIwNjg1OTAwfQ.iz4u9FGgcDPRF41xLGxTBVTV6vWkKJQJ3d0tCteCISI', '555')
// console.log('jmtoken', jmtoken);
// 解析token 会自动生成时间戳字段:“iat”
const {promisify}  = require('util');
const tojwt = promisify(jwt.sign);
const verify = promisify(jwt.verify);
const {uuid} = require('../config/config.default');
// 创建token
module.exports.creatToken = async (obj)=>{const token = await tojwt({obj},  // 加密对象uuid,{expiresIn: '1h'} // 过期时间)return token;
}
// token校验
module.exports.verifyToken = async (req, res, next)=>{const header = req.headers;console.log('header', header)let token = header?.authorization || '';token = token ? token.split('Bearer ')[1] : ''; // 获取tokenif(!token){res.status(402).json({error: '请传入token' })}try {console.log('uuid', uuid)const objToken = await verify(token, uuid); // 解析tokenreq.user = objToken; // 把正确有效的token信息放入请求体usernext() // } catch (error) {res.status(402).json({error: '无效token'})}
}

业务处理模块- controlled文件夹

user.js

  1. 用户注册
const { User } = require('../model/index');
exports.register = async (req, res)=>{console.log(222);const userModel =  new User(req.body);// 保存数据集合const dbback = await userModel.save();let user = dbback.toJSON();// 不给客户端查看用户密码delete user.password;// 返回给客户端注册成功res.status(201).json(user);
}
  1. 查询列表
exports.list =  async (req, res)=>{console.log(22222222, req.user); res.send('/list');
}
  1. 用户登陆
    1.客户端验证数据格式校验middle validator(在路由配置中处理)
    2.链接数据库查询 邮箱和密码校验
exports.login = async (req, res)=>{// 1.客户端验证数据格式校验middle validator// 2.链接数据库查询 邮箱和密码校验let dbback  = await  User.findOne(req.body);if(!dbback) {res.status(402).json({error: "用户名密码不配"})}dbback = dbback.toJSON();dbback.token = await creatToken(dbback);res.status(200).json(token);
}

JWT

  1. JSON Web Token 是目前最流行的跨域认证解决方案

  2. 用户认证的一般流程:
    1.客户端向服务器发送账号和密码。
    2.服务器通过验证后在当前对话session中存放用户数据信息。
    3.服务器向用户端返回session_id 写入用户的cookie。
    4.客户端之后所有需要登录之后才能访问的请求都必须要携带 已经写入session_id的cookie,访问服务端。
    5.服务器拿到session_id 进行校验得知用户是否登录或者是否登录过期。

  3. 一般流程的缺点: 无法实现不同域名网站的跨站登录

  4. 解决方案:JWT方案——服务器不保存 session_id 数据,所有数据都保存在客户端,每次请求都发回服务器.

  5. JWT方案原理:

    1. 服务器认证以后,生成一个 JSON 对象,发回给用户。例子:
      {
      “name”: “Alen”,
      “roll”: “admin”,
      “carrentTime”: “2001-10-10 21:20:00”
      }
    2. 用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份,
    3. 为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名
  6. JWT有三个部分:Header(头部)、Payload(负载)、Signature(签名)

Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用”点”(.)分隔
实际写法:Header.Payload.Signature1.header是json对象{"alg": "HS256", //签名的算法(algorithm) 默认是 HMAC SHA256(写成 HS256)"typ": "JWT" typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。}2.Payload也是json对象{// 内置可选字段iss (issuer):签发人exp (expiration time):过期时间sub (subject):主题aud (audience):受众nbf (Not Before):生效时间iat (Issued At):签发时间jti (JWT ID):编号// 自定义字段}3. Header 和 Payload 串型化的算法是 Base64URL4. Signature  部分是对前两部分的签名,防止数据篡改, secret 为服务器指定的密钥HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)

7.解决跨域
客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。
此后,客户端每次与服务器通信,都要带上这个 JWT。你可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求的头信息Authorization字段里面。 Authorization: Bearer + token
另一种做法是,跨域的时候,JWT 就放在 POST 请求的数据体里面。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • live555 rtsp服务器实战之createNewStreamSource
  • 目标检测--X-anylabeling使用自己的模型自动标注
  • [C++]多态
  • C语言课程回顾:十、C语言之 指针
  • 推荐一款uniapp拖动验证码插件
  • 从LeetCode215看排序算法
  • Nginx集群部署指南:实现高性能和高可用性
  • qt 创建一个可以拖拽的矩形,简单实践
  • 网站架构核心要素
  • [C/C++入门][字符与ASCII码]6、用代码来转换字符与它的ASCII码
  • 【游戏客户端】大话slg玩法架构(三)建筑控件
  • 线性代数|机器学习-P23梯度下降
  • Perl语言之数组
  • 动手学深度学习(1.3.3 - 1.3.4)与环境互动 强化学习
  • 2.5 计算机网络
  • (十五)java多线程之并发集合ArrayBlockingQueue
  • co.js - 让异步代码同步化
  • eclipse的离线汉化
  • js如何打印object对象
  • laravel5.5 视图共享数据
  • Linux下的乱码问题
  • MySQL用户中的%到底包不包括localhost?
  • Node.js 新计划:使用 V8 snapshot 将启动速度提升 8 倍
  • Phpstorm怎样批量删除空行?
  • Terraform入门 - 3. 变更基础设施
  • text-decoration与color属性
  • Traffic-Sign Detection and Classification in the Wild 论文笔记
  • 闭包--闭包之tab栏切换(四)
  • 经典排序算法及其 Java 实现
  • 名企6年Java程序员的工作总结,写给在迷茫中的你!
  • 树莓派 - 使用须知
  • 鱼骨图 - 如何绘制?
  • #07【面试问题整理】嵌入式软件工程师
  • #FPGA(基础知识)
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (SpringBoot)第二章:Spring创建和使用
  • (WSI分类)WSI分类文献小综述 2024
  • (二)构建dubbo分布式平台-平台功能导图
  • (蓝桥杯每日一题)love
  • (企业 / 公司项目)前端使用pingyin-pro将汉字转成拼音
  • (一)Java算法:二分查找
  • (一)搭建springboot+vue前后端分离项目--前端vue搭建
  • (转)http-server应用
  • .htaccess配置重写url引擎
  • .Net - 类的介绍
  • .NET 4.0网络开发入门之旅-- 我在“网” 中央(下)
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET Core IdentityServer4实战-开篇介绍与规划
  • .Net(C#)自定义WinForm控件之小结篇
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .net安装_还在用第三方安装.NET?Win10自带.NET3.5安装
  • .NET高级面试指南专题十一【 设计模式介绍,为什么要用设计模式】
  • .Net开发笔记(二十)创建一个需要授权的第三方组件