开发网页版加密访问文档

开发一个支持加密访问文档的网页版应用程序涉及多个步骤,包括用户认证、文档加密和解密、文件上传和下载,以及确保整个过程中的数据安全性。下面是一个详细的步骤指南:

步骤1:设置项目环境

首先,设置一个新的项目环境。假设你使用的是Node.js和React.js进行前后端开发。

  1. 初始化项目

    sh 复制代码
    npx create-react-app encrypted-docs-app
    cd encrypted-docs-app
    npm init -y
  2. 安装必要的依赖

    sh 复制代码
    npm install express mongoose bcryptjs jsonwebtoken dotenv multer crypto-js
    npm install --save-dev nodemon

步骤2:设置后端(Node.js + Express)

  1. 创建服务器文件

    在项目根目录下创建server.js文件。

    js 复制代码
    const express = require('express');
    const mongoose = require('mongoose');
    const dotenv = require('dotenv');
    const cors = require('cors');
    const authRoutes = require('./routes/auth');
    const docRoutes = require('./routes/docs');
    
    dotenv.config();
    const app = express();
    
    app.use(cors());
    app.use(express.json());
    
    mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
    
    app.use('/api/auth', authRoutes);
    app.use('/api/docs', docRoutes);
    
    const PORT = process.env.PORT || 5000;
    app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
  2. 用户认证

    创建一个新的目录routes,并在其中创建auth.js文件。

    js 复制代码
    const express = require('express');
    const bcrypt = require('bcryptjs');
    const jwt = require('jsonwebtoken');
    const User = require('../models/User');
    
    const router = express.Router();
    
    // 注册
    router.post('/register', async (req, res) => {
        const { username, password } = req.body;
        const salt = await bcrypt.genSalt(10);
        const hashedPassword = await bcrypt.hash(password, salt);
        const newUser = new User({ username, password: hashedPassword });
    
        try {
            const savedUser = await newUser.save();
            res.status(201).json(savedUser);
        } catch (err) {
            res.status(400).json(err);
        }
    });
    
    // 登录
    router.post('/login', async (req, res) => {
        const { username, password } = req.body;
        try {
            const user = await User.findOne({ username });
            if (!user) return res.status(400).json({ message: "User not found" });
    
            const isMatch = await bcrypt.compare(password, user.password);
            if (!isMatch) return res.status(400).json({ message: "Invalid credentials" });
    
            const token = jwt.sign({ id: user._id }, process.env.JWT_SECRET, { expiresIn: '1h' });
            res.status(200).json({ token });
        } catch (err) {
            res.status(500).json(err);
        }
    });
    
    module.exports = router;
  3. 文档上传和下载

    routes目录下创建docs.js文件。

    js 复制代码
    const express = require('express');
    const multer = require('multer');
    const jwt = require('jsonwebtoken');
    const fs = require('fs');
    const crypto = require('crypto');
    const path = require('path');
    
    const router = express.Router();
    
    const storage = multer.diskStorage({
        destination: (req, file, cb) => {
            cb(null, 'uploads/');
        },
        filename: (req, file, cb) => {
            cb(null, `${file.fieldname}-${Date.now()}${path.extname(file.originalname)}`);
        }
    });
    
    const upload = multer({ storage });
    
    // 中间件验证JWT
    const verifyToken = (req, res, next) => {
        const token = req.header('x-auth-token');
        if (!token) return res.status(401).json({ message: 'No token, authorization denied' });
    
        try {
            const decoded = jwt.verify(token, process.env.JWT_SECRET);
            req.user = decoded;
            next();
        } catch (err) {
            res.status(400).json({ message: 'Token is not valid' });
        }
    };
    
    // 文件加密
    const encryptFile = (filePath) => {
        const cipher = crypto.createCipher('aes-256-ctr', process.env.ENCRYPTION_SECRET);
        const input = fs.createReadStream(filePath);
        const output = fs.createWriteStream(`${filePath}.enc`);
    
        input.pipe(cipher).pipe(output);
    };
    
    // 文件解密
    const decryptFile = (filePath, res) => {
        const decipher = crypto.createDecipher('aes-256-ctr', process.env.ENCRYPTION_SECRET);
        const input = fs.createReadStream(filePath);
        const output = res;
    
        input.pipe(decipher).pipe(output);
    };
    
    // 上传文档
    router.post('/upload', verifyToken, upload.single('document'), (req, res) => {
        const filePath = req.file.path;
        encryptFile(filePath);
        fs.unlinkSync(filePath); // 删除原始文件,保留加密文件
        res.status(200).json({ message: 'File uploaded and encrypted successfully' });
    });
    
    // 下载文档
    router.get('/download/:filename', verifyToken, (req, res) => {
        const filePath = `uploads/${req.params.filename}`;
        decryptFile(filePath, res);
    });
    
    module.exports = router;
  4. 创建用户模型

    models目录下创建User.js文件。

    js 复制代码
    const mongoose = require('mongoose');
    
    const UserSchema = new mongoose.Schema({
        username: { type: String, required: true, unique: true },
        password: { type: String, required: true },
    });
    
    module.exports = mongoose.model('User', UserSchema);

步骤3:设置前端(React)

  1. 创建登录和注册页面

    src目录下创建components目录,并在其中创建Login.jsRegister.js文件。

    jsx 复制代码
    // src/components/Register.js
    import React, { useState } from 'react';
    import axios from 'axios';
    
    const Register = () => {
        const [username, setUsername] = useState('');
        const [password, setPassword] = useState('');
    
        const handleSubmit = async (e) => {
            e.preventDefault();
            try {
                const res = await axios.post('http://localhost:5000/api/auth/register', { username, password });
                console.log(res.data);
            } catch (err) {
                console.error(err);
            }
        };
    
        return (
            <form onSubmit={handleSubmit}>
                <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" />
                <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" />
                <button type="submit">Register</button>
            </form>
        );
    };
    
    export default Register;
    jsx 复制代码
    // src/components/Login.js
    import React, { useState } from 'react';
    import axios from 'axios';
    
    const Login = ({ setToken }) => {
        const [username, setUsername] = useState('');
        const [password, setPassword] = useState('');
    
        const handleSubmit = async (e) => {
            e.preventDefault();
            try {
                const res = await axios.post('http://localhost:5000/api/auth/login', { username, password });
                setToken(res.data.token);
            } catch (err) {
                console.error(err);
            }
        };
    
        return (
            <form onSubmit={handleSubmit}>
                <input type="text" value={username} onChange={(e) => setUsername(e.target.value)} placeholder="Username" />
                <input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="Password" />
                <button type="submit">Login</button>
            </form>
        );
    };
    
    export default Login;
  2. 创建文档上传和下载页面

    src/components目录下创建Upload.jsDownload.js文件。

    jsx 复制代码
    // src/components/Upload.js
    import React, { useState } from 'react';
    import axios from 'axios';
    
    const Upload = ({ token }) => {
        const [file, setFile] = useState(null);
    
        const handleFileChange = (e) => {
            setFile(e.target.files[0]);
        };
    
        const handleSubmit = async (e) => {
            e.preventDefault();
            const formData = new FormData();
            formData.append('document', file);
    
            try {
                await axios.post('http://localhost:5000/api/docs/upload', formData, {
                    headers: {
                        'Content-Type': 'multipart/form-data',
                        'x-auth-token': token
                    }
                });
                alert('File uploaded and encrypted successfully');
            } catch (err) {
                console.error(err);
            }
        };
    
        return (
            <form onSubmit={handleSubmit}>
               

Upload ); };

export default Upload;

```jsx
// src/components/Download.js
import React, { useState } from 'react';
import axios from 'axios';

const Download = ({ token }) => {
    const [filename, setFilename] = useState('');

    const handleSubmit = async (e) => {
        e.preventDefault();
        try {
            const res = await axios.get(`http://localhost:5000/api/docs/download/${filename}`, {
                headers: {
                    'x-auth-token': token
                },
                responseType: 'blob'
            });

            const url = window.URL.createObjectURL(new Blob([res.data]));
            const link = document.createElement('a');
            link.href = url;
            link.setAttribute('download', filename);
            document.body.appendChild(link);
            link.click();
        } catch (err) {
            console.error(err);
        }
    };

    return (
        <form onSubmit={handleSubmit}>
            <input type="text" value={filename} onChange={(e) => setFilename(e.target.value)} placeholder="Filename" />
            <button type="submit">Download</button>
        </form>
    );
};

export default Download;
  1. 设置App组件和路由

    修改src/App.js文件,整合上述组件并设置路由。

    jsx 复制代码
    // src/App.js
    import React, { useState } from 'react';
    import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
    import Login from './components/Login';
    import Register from './components/Register';
    import Upload from './components/Upload';
    import Download from './components/Download';
    
    const App = () => {
        const [token, setToken] = useState('');
    
        return (
            <Router>
                <div>
                    <Switch>
                        <Route path="/register">
                            <Register />
                        </Route>
                        <Route path="/login">
                            <Login setToken={setToken} />
                        </Route>
                        <Route path="/upload">
                            <Upload token={token} />
                        </Route>
                        <Route path="/download">
                            <Download token={token} />
                        </Route>
                        <Route path="/">
                            <h1>Welcome to Encrypted Docs App</h1>
                        </Route>
                    </Switch>
                </div>
            </Router>
        );
    };
    
    export default App;

总结

通过上述步骤,你可以开发一个支持加密访问文档的网页版应用程序。该应用程序包括用户认证、文件上传与下载、文件加密与解密等功能,确保文档的安全性。

相关推荐
白水先森14 小时前
ArcGIS Pro制作人口三维地图教程
arcgis·信息可视化·数据分析
摆烂老大1 天前
SWAT| 水文 | SWAT模型(四):气象数据库制备(附Python代码)
python·arcgis·水文·swat模型
GIS遥感数据处理应用1 天前
MATLAB | 设置滑动窗口计算栅格数据的CV变异系数
matlab·arcgis·数据分析
白水先森1 天前
ArcGIS Pro进行坡度与坡向分析
经验分享·arcgis
GZ同学1 天前
Arcmap和ArcgisPro重装及配置迁移
arcgis
白水先森2 天前
ArcGIS Pro中等高线的生成与应用详解
经验分享·arcgis·信息可视化
白水先森2 天前
如何利用ArcGIS Pro打造萤火虫风格地图
经验分享·arcgis
角砾岩队长4 天前
ArcGIS笔记之度分秒与十进制度的转换
笔记·arcgis
yngsqq7 天前
关于arcgis中坐标系、投影的一些知识
arcgis
李建军7 天前
ArcGISPro 新建shp+数据结构
arcgis