bcrypt 密码加密
项目中使用:
utils/tool.js
const bcrypt = require('bcrypt')
const fs = require('fs')
const path = require('path')
const jwt = require('jsonwebtoken')
exports.hash = (myPlaintextPassword) => {
return new Promise((resolve, reject) => {
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
if (err) {
reject(err)
}
resolve(hash)
})
})
})
}
调用 -> controller/user.js
const { hash } = require('../utils/tools')
// 注册用户
const signup = async (req, res, next) => {
res.set('content-type', 'application/json; charset=utf-8')
const { username, password } = req.body
// 密码加密
const bcryptPassword = await hash(password)
// 判断用户是否存在
let findResult = await usersModel.findUser(username)
if (findResult) {
res.render('fail', {
data: JSON.stringify({
message: '用户名已存在。'
})
})
} else {
// 数据库里没有这个用户,开始添加用户
let result = await usersModel.signup({
username,
password: bcryptPassword
})
res.render('succ', {
data: JSON.stringify({
message: '注册成功!'
})
})
}
}
登录的时候验证用户和密码,跟加密的密码与登录时候的密码进行对比
utils/tool.js
const bcrypt = require('bcrypt')
const fs = require('fs')
const path = require('path')
const jwt = require('jsonwebtoken')
exports.hash = (myPlaintextPassword) => {
return new Promise((resolve, reject) => {
bcrypt.genSalt(10, function(err, salt) {
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
if (err) {
reject(err)
}
resolve(hash)
})
})
})
}
exports.compare = (myPlaintextPassword, hash) => {
return new Promise((resolve, reject) => {
bcrypt.compare(myPlaintextPassword, hash, function(err, result) {
resolve(result)
})
})
}
controllers/users.js
const usersModel = require('../models/users')
const { hash, compare, sign, verify } = require('../utils/tools')
// const randomstring = require("randomstring")
// 注册用户
const signup = async (req, res, next) => {
res.set('content-type', 'application/json; charset=utf-8')
const { username, password } = req.body
// 密码加密
const bcryptPassword = await hash(password)
// 判断用户是否存在
let findResult = await usersModel.findUser(username)
if (findResult) {
res.render('fail', {
data: JSON.stringify({
message: '用户名已存在。'
})
})
} else {
// 数据库里没有这个用户,开始添加用户
let result = await usersModel.signup({
username,
password: bcryptPassword
})
res.render('succ', {
data: JSON.stringify({
message: '注册成功!'
})
})
}
}
// 用户登录
const signin = async (req, res, next) => {
const { username, password } = req.body
let result = await usersModel.findUser(username)
// 验证用户是否是合法用户
if (result) {
let { password: hash } = result
let compareResult = await compare(password, hash)
if (compareResult) {
// req.session.username = username
const token = sign(username)
res.set('Access-Control-Expose-Headers', 'X-Access-Token')
res.set('X-Access-Token', token)
res.render('succ', {
data: JSON.stringify({
username
})
})
} else {
res.render('fail', {
data: JSON.stringify({
message: '用户名或密码错误。'
})
})
}
} else {
res.render('fail', {
data: JSON.stringify({
message: '用户名或密码错误。'
})
})
}
}
cros 解决跨域
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。使用 Express 可以快速地搭建一个完整功能的网站
npm i express 或者 npm install express # 首先安装服务器模块
npm i cors 或者 npm install cors # 再安装解决跨域模块
npm i axios # 用来发送请求
const express = require(‘express’);
const cors = require(‘cors’);
const app = express(); # 初始化模块创建个对象
app.use(express.json()); # 解析json编码数据
app.use(express.urlencoded()); # 解析url编码的数据
app.use(cors()); # 不加上这句代码跨域访问时会出现错误,加上就不会出现跨域错误情况
进行各种方式的请求, 第一个参数都是路由,提供给前端的接口做代理用,以post方式举例,提供一个代理服务器
用nodejs请求数据然后把数据返回给前端就行
app.post("/api", (req, res) => {
const { url } = req.body;
// console.log(req.body);
axios.get(url)
.then(result => {
res.json(result.data);
})
.catch(err => {
console.error(err);
})
})
第一个参数是端口号
app.listen(3000, ()=>{
console.log(“运行在3000端口”)
});
前端通过访问后端提供的接口
$.post(“后端接口”,
把需要请求数据的网址传给nodejs后端
{ url: “要请求数据的网址” })
.then(res => {
console.log(res) # 最后后端把请求的数据返回给前端,这样就解决了跨域,但是是由后端解决的
})
.catch(err => {
console.error(err);
})
proxy跨域
node中使用session
安装
npm install cookie-session
导入
var cookieSession = require('cookie-session')
使用
var cookieSession = require('cookie-session')
var express = require('express')
var app = express()
app.set('trust proxy', 1) // trust first proxy
app.use(cookieSession({
name: 'session',
keys: ['key1', 'key2']
}))
app.use(function (req, res, next) {
// Update views
req.session.views = (req.session.views || 0) + 1
// Write response
res.end(req.session.views + ' views')
})
app.listen(3000)
移除
req.session = null
jwt(token验证)
使用地址
安装
npm install jsonwebtoken
导入
var jwt = require('jsonwebtoken');
对称加密
使用对称加密
// sign with RSA SHA256
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
//{ foo: 'bar' } 将这个对象加入到返回的消息
//shhhhh 加密数据
进行token验证
// sign with RSA SHA256
var jwt = require('jsonwebtoken');
var token = jwt.sign({ foo: 'bar' }, 'shhhhh');
//{ foo: 'bar' } 将这个对象加入到返回的消息
//shhhhh 加密数据
// verify a token symmetric
// 验证
jwt.verify(token, 'shhhhh', function(err, decoded) {
console.log(decoded.foo) // bar
});
非对称加密
秘钥生成
openssl
genrsa -out rsa_private_key.pem 2048
根据私钥生成公钥:
rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
使用非对称
exports.sign = (username) => {
const privateKey = fs.readFileSync(path.join(__dirname, '../keys/rsa_private_key.pem'))
const token = jwt.sign({username}, privateKey, { algorithm: 'RS256' })
return token
}
// 读取生成的私钥文件,拿到私钥
// ({username} 将这个对象携带在返回的信息中,根据privateKey和{ algorithm: 'RS256' }生成token
进行token验证
exports.verify = (token) => {
const publicKey = fs.readFileSync(path.join(__dirname, '../keys/rsa_public_key.pem'))
const result = jwt.verify(token, publicKey)
return result
}
// 读取生成的公钥文件,拿到公钥
// token 前端返回的token publicKey 公钥,使用公钥以及token进行验证
网上验证
对称验证
设置验证方式
放入token
放入加密信息(白色框)
非对称验证
设置验证方式
放入token
放入公钥(第一个白色框)
放入私钥(第二个白色框)
token无效或者token过期的处理
let token = req.headers.authorization;
if (token) {
jwt.verify(token, 'secret', (err, decoded) => {
if (err) {
switch (err.name) {
case 'JsonWebTokenError':
res.status(403).send({ code: -1, msg: '无效的token' });
break;
case 'TokenExpiredError':
res.status(403).send({ code: -1, msg: 'token过期' });
break;
}
}
})
}
socket
实现图片上传
multer用来上传图片
使用地址
安装:
$ npm install --save multer
使用: 创建文件 - 项目目录/midderWare/multer.js
const multer = require('multer')
const path = require('path')
const mime = require('mime');
let fullFileName = ''
const storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, path.join(__dirname, '../public/uploads'))
},
filename: function (req, file, cb) {
fullFileName = (file.fieldname + '-' + Date.now() + '.'+ mime.getExtension(file.mimetype))
cb(null, fullFileName)
req.fullFileName = 'http://localhost:8000/uploads/' + fullFileName
}
})
const uploadMidder = multer({ storage: storage })
exports.uploadMidder = uploadMidder
需要安装mime
mime主要来获取后缀名
安装 :
npm install mime
使用地址mime
或者使用下面这种来获取后缀名
file.originalname.split('.')[1]
调用multer文件
在项目目录/router/index.js 添加方法中使用muter做中间件
var express = require('express')
var router = express.Router()
const { list, deleted, add, update, } = require('../controller/index')
const { uploadMidder } = require('../middleWare/mullter')
router.get('/', list)
router.post('/', uploadMidder.array('photos', 12), add)
router.post('/update', update)
router.delete('/deleted/:id', deleted)
module.exports = router
将得到的muter.js中的fullFileName添加到后台
在项目目录/controller/index.js 添加方法add中拿到传入过来的fullFileName,添加到前台返回过来的数据req.body中
然后再数据库中就可以看到图片的路径了
“http://localhost:8000/uploads/photos-1632144850817.jpeg”
之后在node中,开放静态文件
app.js 添加
// 开发静态资源
app.use(express.static('public'))
前台拿到添加的数据
之后用img标签显示上方图片的路径就可以显示图片了