nodejs设置加密目录(Node.jsKoa用户登录)
nodejs设置加密目录(Node.jsKoa用户登录)<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Form表单上传</title> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script> <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet"> </head>
工程结构安装命令
npm init -y
npm install dotenv
npm install koa
npm install koa-Router
npm install koa-body
npm install koa-static
npm install bcryptjs
版本
"bcryptjs": "^2.4.3"
"dotenv": "^16.0.1"
"koa": "^2.13.4"
"koa-body": "^5.0.0"
"koa-router": "^10.1.1"
"koa-static": "^5.0.0"
项目代码
src\main.js
const app = require('./app/index');
const {APP_PORT} = require('./config/config.default');
app.listen(APP_PORT function(){
console.log("listen port :" APP_PORT);
});
src\app\index.js
const Koa = require('koa');
const userRouter = require('../router/user.router');
const app = new Koa();
const path = require('path');
const KoaBody = require('koa-body');
const KoaStatic = require('koa-static');
// 中间件顺序
app.use(
KoaBody({
multipart: true
formidable: {
// 在配制选项option里 不推荐使用相对路径
// 在option里的相对路径 不是相对的当前文件. 相对process.cwd()
uploadDir: path.join(__dirname '../upload')
keepExtensions: true
}
parsedMethods: ['POST' 'PUT' 'PATCH' 'DELETE']
})
)
// 静态文件(http://127.0.0.1:3000/62a9e1a775cab5e7f484f9b00.jpg)
app.use(KoaStatic(path.join(__dirname '../upload')));
//
app.use(userRouter.routes()).use(userRouter.allowedMethods());
module.exports = app;
src\config\config.default.js
const dotenv = require('dotenv');
dotenv.config();
module.exports = process.env;
src\router\user.router.js
const Router = require('koa-router');
const router = new Router({ prefix: '/user' });
const fs = require("fs");
const path = require('path');
const { login upload } = require('../controller/user.controller');
/**
* 显示登录页面
*/
router.get('/login' async (ctx next) => {
let res = await fs.readFileSync(path.join(__dirname '../static/login.html'));
ctx.set('Content-Type' 'text/html;charset=utf-8');
ctx.body = res;
});
/**
* 提交数据
*/
router.post('/login' login);
router.get('/upload' async (ctx next) => {
let res = await fs.readFileSync(path.join(__dirname '../static/upload.html'));
ctx.set('Content-Type' 'text/html;charset=utf-8');
ctx.body = res;
});
/**
* 文件上传
*/
router.post('/upload' upload);
/**
* 文件下载 <Method Not Allowed>
* http://127.0.0.1:3000/user/download/62a9e1a775cab5e7f484f9b00.jpg
*/
router.post('/download/:name' async (ctx next) => {
const name = ctx.request.params.name;
ctx.type = 'image/jpeg';
ctx.body = fs.createReadStream(path.join(__dirname '../upload/' name));
});
module.exports = router;
src\static\login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>用户登录</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container " style="width:600px;">
<span>
<h1>用户登录</h1>
</span>
<form method="post" action="/user/login">
<div class="form-group">
<label for="username">用户名:</label>
<input id="username" name="username" type="text" class="form-control" value="" />
</div>
<div class="form-group">
<label for="password">密码:</label>
<input id="password" name="password" type="password" class="form-control" value="" />
</div>
<button type="reset" class="btn btn-secondary">取消</button>
<button type="submit" class="btn btn-danger">登录</button>
</form>
</div>
</body>
</html>
src\static\upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Form表单上传</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container " style="width:600px;">
<span>
<h1>Form表单上传</h1>
</span>
<form method="post" action="/user/upload" enctype="multipart/form-data">
<input type="hidden" name="model" value="object" />
<div class="form-group">
<label for="File1">上传文件1:</label>
<input id="file1" type="file" name="file1" value="" class="form-control" />
</div>
<div class="form-group">
<label for="file2">上传文件2:</label>
<input id="file2" type="file" name="file2" value="" class="form-control" />
</div>
<div class="form-group">
<label for="desc">描述:</label>
<textarea id="desc" name="desc" class="form-control" style="min-height: 200px;"></textarea>
</div>
<div class="form-group form-check">
<label class="form-check-label">
<input class="form-check-input" type="checkbox">记住我
</label>
</div>
<button type="reset" class="btn btn-secondary">取消</button>
<button type="submit" class="btn btn-danger">提交</button>
</form>
</div>
</body>
</html>
src\controller\user.controller.js
const bcrypt = require('bcryptjs');
class UserController {
/**
* 登录
*/
async login(ctx next) {
// 获取数据
console.log("ctx.request.body" ctx.request.body)
const { username password } = ctx.request.body;
// 校验合法性
if (!username || !password) {
console.error('用户名或密码为空' ctx.request.body)
ctx.status = 400;
ctx.body = {
code: '10001'
message: '用户名或密码为空'
result: ''
}
return;
}
// 加密, hash保存的是 密文
const salt = bcrypt.genSaltSync(10)
const hash = bcrypt.hashSync(password salt);
console.log("加密后的密文:" hash);
// 123456
let safePassword = '$2a$10$SbmVLoEz7N0rY0zxiYYyR.lx4.71wzc7GIak0OLt65e7T0ZIeGRSW';
// 密码是否匹配(不匹配: 报错)
if (!bcrypt.compareSync(password safePassword)) {
ctx.body = {
code: '10002'
message: '用户名或密码错误'
result: ''
}
return;
}
// 返回结果
// ctx.body = ctx.request.body;
ctx.body = {
code: 0
message: '用户登录成功'
result: {
id: 1
username: username
password: hash
}
}
}
/**
* 上传
*/
async upload(ctx next) {
console.log(ctx.request.files)
const { file1 file2 } = ctx.request.files;
const fileTypes = ['image/jpeg' 'image/png']
if (file1 && file2) {
if (!fileTypes.includes(file1.mimetype)) {
ctx.body = {
code: '20001'
message: '上传文件类型不支持'
result: ''
}
return;
}
ctx.body = {
code: 0
message: '商品图片上传成功'
result: {
newFilename: file1.newFilename
}
}
} else {
ctx.body = {
code: '20002'
message: '上传文件错误'
result: ''
}
return;
}
}
}
module.exports = new UserController();