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();          




