总结及补充内容

内容回顾

node是一个服务端的js,他的底层内核是V8引擎。

相关的指令及工具

nvm node的版本管理工具(需要安装)

nrm node的镜像管理工具(需要安装)

npx 快速执行脚本的命令

npm 包管理器

node 运行js文件的

包管理工具

npm 

npm i 第三方模块   #npm安装

yarn (Facebook出品)

yarn add 第三方模块  #yarn安装

基础npm指令

  • npm install 安装 简写为 npm i 
  • npm uninstall 卸载
  • npm update 更新
  • npm publish 发布
  • npm set 设置
  • npm config 配置
  • ...

命令修饰关键词

  • -S 保存到本地  --save
  • -D 保存到工作环境  --develop
  • -g 全局保存 --global

内置模块及第三方模块

内置模块(不需要安装)

http(处理http请求),url模块处理url,path模块路径处理,querystring(qs)读取对应的内容 fs模块filesystem...

第三方模块(需要安装)

md5 加密模块  uuid形成id模块  mysql模块  mongodb模块 body-parse模块  cookie-parse模块  express模块...

模块化(require.js的模块化)

require 导入

const http = require("http")

module.exports 导出

module.exports = { }

内置加密模块 crypto

导入模块

const {createHmac} = require('node:crypto');

接口书写

//用户登录操作
router.post("/login", async function (req, res, next) {
//获取用户名及密码
let {
username,
password
} = req.body
//对应的密码要进行加密操作再进行验证 密钥
let checks = await queryUserByUser({
username
})
//如果用户名存在
if (checks.length) {
//验证当前是否正确 获取当前用户
let user = checks[0]
//密码要进行加密操作 user.slat
password = createHmac("sha256", user.slat).update(password).digest("hex")
//判断当前user密码是否和对应的加密密码一致
if (user.password == password) {
res.send(new Response({
id: user.id
}, 200, "登录成功"))
} else {
res.send(new Response({}, 200, "用户名或密码错误"))
}
}else {
res.send(new Response({}, 200, "用户名或密码错误"))
}
})
//用户注册操作
router.post("/register", async function (req, res, next) {
//获取用户信息
let {
username,
password
} = req.body
//查询当前用户是否存在
let users = await queryUserByUser({
username
})
//查不到注册
if (!users.length) {
//对密码进行加密操作
//随机生成对应的盐值
req.body.slat = Math.ceil(Math.random() * 1000) + Date.now().toString()
req.body.password = createHmac("sha256",
req.body.slat).update(password).digest("hex")
//指定默认值
await saveUser(req.body)
//注册成功
res.send(new Response(req.body, 200, "注册成功"))
} else {
res.send(new Response({}, 200, "当前用户已存在"))
}
})

第三方模块 jwt

jwt概述

json web token主要是用于安全传输,里面主要有授权和加密等操作。JSON WEB Token(JWT,读作 [/dʒɒt/] ),是一种基于JSON的,用于在网络上声明某种主张的令牌(token)。JWT通常由三部分组成:头信息(header),消息体(payload)和签名(signature)。

jwt的简单构成

密钥   (加密方式   hash加密  对称加密  非对称加密(rsa))

信息   (关键信息   用户id等标识信息)

过期时间      (为毫秒值)

jsonwebtoken || express-jwt (导入了jwt模块)

流程

  • 先拦截对应的需要权限进入的接口  放行不需要拦截的接口(登录、注册)
//中间件拦截 参数1为密钥 参数2为加密方式
app.use(jwt({secret:privateKey,algorithms:["RS256"]}).unless({
path:["/users/login","/users/register"]
}))
  • 登录成功生成对应的token发送到浏览器上
//用户登录操作
router.post("/login", async function (req, res, next) {
//获取用户名及密码
let {
username,
password
} = req.body
//对应的密码要进行加密操作再进行验证 密钥
let checks = await queryUserByUser({
username
})
//如果用户名存在
if (checks.length) {
//验证当前是否正确 获取当前用户
let user = checks[0]
//密码要进行加密操作 user.slat
password = createHmac("sha256",
user.slat).update(password).digest("hex")
//判断当前user密码是否和对应的加密密码一致
if (user.password == password) {
//生成token
//sign方法 第一个为数据 第二个为私钥 第三为配置
let token = sign({id:user.id},privateKey,{
algorithm:"RS256",
//过期时间为s
expiresIn: 120
})
//生成对应的token
res.send(new Response({
id: user.id,
token
}, 200, "登录成功"))
} else {
res.send(new Response({}, 200, "用户名或密码错误"))
}
}else {
res.send(new Response({}, 200, "用户名或密码错误"))
}
})
  • 再次请求需要拦截的接口 需要带上对应的token

存对应的登录返回的token(localstroage  || sessionstroage)

localstroage.setItem("token",token) //存入token到本地

从本地获取token存入对应的请求头

//请求头中添加对应的token
req.headers["Authorization"] = "Bearer"+从本地拿的token

 后台解析

// 获取所有的用户
router.get('/', async function (req, res, next) {
let users = await getUsers()
//得到token字符串 Bearer token
let tokenStr = req.headers["authorization"].split(" ")[1]
//解析token 取出里面的数据
let payload = verify(tokenStr,publicKey,{
algorithms:["RS256"]
})
//根据id得到相关数据 (得到当前用户的权限)
res.send(new Response(users)).status(200)
});

密钥生成

  • 对称加密 (加密和解密是一个)
  • 非对称加密 (非对称加密 公钥 及 私钥)

借助openSSL 来完成密钥的生成

安装openSSL(部分电脑内置)

openSSL version -a

生成私钥

 openssl genrsa -out private.key

根据私钥生成公钥

openssl rsa -in private.key -pubout -out public.key

读取key的工具

const fs = require("fs")
const {join} = require("path")
let privateKey = fs.readFileSync(join(__dirname,"../key/private.key"))
let publicKey =fs.readFileSync(join(__dirname,"../key/public.key"))
module.exports = {
privateKey,
publicKey
}

axios

概述

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

axios的特点

axios的简单使用

直接使用axios里面的方法 (返回的是promise对象)

  • axios.get
  • axios.post
  • axios.delete
  • axios.put
  • axios.patch
  • ....
<button>登录</button>
<!-- cdn引入 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
async function login(){
//发送get请求 请求地址 参数
let info = await axios.post("http://localhost:3000/users/login",{
username:'jack',
password:'123'
})
console.log(info)
}
document.querySelector("button").onclick = ()=>{
login()
}
</script>

二次封装

将对应的axiso封装成一个文件 返回一个对应的axios的请求方法

<button class="login">登录封装版</button>
<button class="getUsers">获取users数据</button>
<!-- cdn引入 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script>
var request = axios.create({
baseURL: 'http://localhost:3000',
timeout: 3000,
})
//封装对应的axios
//请求拦截
request.interceptors.request.use(config => {
//获取本地的token加入到对应的headers中
config.headers["Authorization"] = "Bearer"+localStorage.getItem("token")
return config;
}, error => {
console.log("请求出错")
return Promise.reject(error);
});
//响应拦截
request.interceptors.response.use(response => {
//使用localstroage存入 获取的token
let token = response.data.data.token
//存入对应的localstroage中
localStorage.setItem("token",token)
return response;
}, error => {
//如果响应过期了 那么应该去登录页面
if(error.response.status == 401){
console.log("去登陆页面")
}
return Promise.reject(error);
});
async function loginAxios() {
//发送get请求 请求地址 参数
let info = await request({
method: "post",
url: '/users/login',
data: {
username:'jack',
password: '123'
}
})
console.log(info)
}
document.querySelector(".login").onclick = () => {
loginAxios()
}
document.querySelector(".getUsers").onclick = async () => {
console.log("触发了")
let info = await request({
method: "get",
url: '/users',
data:{}
})
console.log(info)
}
</script>

请求拦截

//获取localstroage中的token 将token加入到对应的请求头
//获取本地的token加入到对应的headers中
config.headers["Authorization"] = "Bearer "+localStorage.getItem("token")

响应拦截

//获取响应的token 将token存入本地 (localstroage)
//使用localstroage存入 获取的token
let token = response.data.data.token
//存入对应的localstroage中
localStorage.setItem("token",token)

上传功能实现

第三方模块 multer

npm i multer -S

上传工具类封装

var multer = require("multer")
var path = require("path")
var {mkdirSync,existsSync} = require("fs")
//帮助类完成对应的上传
//自定义上传的相关信息
const storage = multer.diskStorage({
destination: function (req, file, cb) {
let uploadPath = "../public/upload"
//判断路径是否存在
if(!existsSync(path.join(__dirname,uploadPath))){
// 如果不存在就创建
mkdirSync(path.join(__dirname,uploadPath))
}
cb(null, path.join(__dirname,uploadPath))
},
filename: function (req, file, cb) {
//随机生成的名字
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1000)
cb(null, file.fieldname + '-' + uniqueSuffix +
path.extname(file.originalname) )
}
})
//产生对应的上传的方法
const upload = multer({
storage: storage
})
module.exports = upload

基础使用

页面

<!DOCTYPE html>
<html>
<head>
<title>上传页面</title>
<link rel='stylesheet' href='/stylesheets/style.css' />
</head>
<body>
<form action="http://localhost:3000/upload" method="post"
enctype="multipart/form-data">
<input type="file" name="file">
<button type="submit">上传</button>
</form>
</body>
</html>

接口

//上传页面接口
router.get('/upload.html', function (req, res, next) {
res.render('upload');
});
//upload.single('属性名') 表示上传一个文件
//upload.array([]) 表示上传多个文件
//上传接口
router.post('/upload', upload.single('file'),function (req, res, next) {
console.log('进来了')
//完成上传操作
console.log(req.file, req.body)
res.send({
fileName:req.file.filename,
path:"http://localhost:3000/upload/"+req.file.filename
})
});

中间件拦截

//中间件拦截 参数1为密钥 参数2为加密方式
app.use(jwt({secret:publicKey,algorithms:["RS256"]}).unless({
path:["/users/login","/users/register","/",/upload/] //其中带upload的内容不需要拦
截
}))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值