📅  最后修改于: 2023-12-03 15:38:05.169000             🧑  作者: Mango
在实际开发中,文件上传对于网站或者应用程序来说是非常常见的。然而,在一些敏感数据的上传过程中,我们需要保证上传者的身份合法,否则可能会出现安全问题。
本文将介绍如何使用 Node.js 在文件上传中添加身份验证,以保证上传者的身份合法性。
在实现文件上传及身份验证之前,我们需要安装一些必要的依赖。具体可使用以下命令进行安装:
npm install express multer bcrypt jsonwebtoken
其中,express
是一个常用的 Node.js web 框架,用于处理 HTTP 请求和响应;multer
用于文件上传和处理;bcrypt
用于密码哈希,用于加密密码;jsonwebtoken
用于生成 JSON Web Tokens,用于身份验证。
首先,我们需要实现文件上传的功能。具体可以使用 multer
库实现,使用方法如下:
const express = require('express');
const multer = require('multer');
const app = express();
// 设置上传目录
const storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, 'uploads/');
},
filename: function(req, file, cb) {
cb(null, Date.now() + '-' + file.originalname);
},
});
// 设置上传文件的限制
const fileFilter = function(req, file, cb) {
if (
file.mimetype === 'image/png' ||
file.mimetype === 'image/jpeg' ||
file.mimetype === 'image/gif'
) {
cb(null, true);
} else {
cb(
new Error('Invalid file type. Only jpg, png and gif image files are allowed.'),
false,
);
}
};
// 初始化 multer
const upload = multer({
storage: storage,
fileFilter: fileFilter,
}).single('file');
// 文件上传接口
app.post('/upload', (req, res) => {
upload(req, res, function(err) {
if (err instanceof multer.MulterError) {
// A Multer error occurred when uploading.
res.status(400).json({ error: err.message });
} else if (err) {
// An unknown error occurred when uploading.
res.status(400).json({ error: err.message });
} else {
// Everything went fine.
res.status(200).json({ fileUrl: `http://localhost:3000/${req.file.path}` });
}
});
});
app.listen(3000, () => console.log('Server running on port 3000'));
上述代码中,我们首先使用 multer
实例化一个上传对象,设置上传目录和限制文件类型等信息。在路由处理函数中,使用 upload
函数进行文件上传。
接下来,我们需要在文件上传过程中添加身份验证。具体可以使用 jsonwebtoken
库和 bcrypt
库实现。首先,我们需要添加用户注册和登录功能:
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const users = [];
// 用户注册
app.post('/register', (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ error: 'Username and password are required.' });
}
const user = users.find((u) => u.username === username);
if (user) {
return res.status(400).json({ error: 'Username already exists.' });
}
bcrypt.hash(password, 10, function(err, hash) {
if (err) {
return res.status(500).json({ error: err.message });
}
const newUser = {
username,
password: hash,
};
users.push(newUser);
return res.status(201).json({ message: 'User registered successfully.' });
});
});
// 用户登录
app.post('/login', (req, res) => {
const { username, password } = req.body;
if (!username || !password) {
return res.status(400).json({ error: 'Username and password are required.' });
}
const user = users.find((u) => u.username === username);
if (!user) {
return res.status(400).json({ error: 'Invalid credentials.' });
}
bcrypt.compare(password, user.password, function(err, result) {
if (err) {
return res.status(500).json({ error: err.message });
}
if (!result) {
return res.status(400).json({ error: 'Invalid credentials.' });
}
const token = jwt.sign({ username: user.username }, 'secretkey', { expiresIn: '1h' });
return res.status(200).json({ token });
});
});
上述代码中,我们首先定义一个用户数组 users
,用于存储注册的用户数据。对于用户注册,我们先判断用户名和密码是否传递过来,然后判断用户名是否已存在。如果不存在,则使用 bcrypt
对密码进行哈希,并将用户信息添加到数组中。对于用户登录,我们先判断用户名和密码是否传递过来,然后查找目标用户,并使用 bcrypt
校验密码是否正确。如果正确,则使用 jsonwebtoken
生成一个 JSON Web Token,并将其作为响应返回给客户端。
然后,我们需要在文件上传接口中添加身份验证:
// 身份验证中间件
const verifyToken = function(req, res, next) {
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1];
if (!token) {
return res.status(401).json({ error: 'Access denied. No token provided.' });
}
try {
const decoded = jwt.verify(token, 'secretkey');
req.user = decoded;
next();
} catch (ex) {
res.status(400).json({ error: 'Invalid token.' });
}
};
// 文件上传接口
app.post('/upload', verifyToken, (req, res) => {
// ...
});
上述代码中,我们首先定义了一个 verifyToken
中间件,用于验证用户是否提供了有效的 JSON Web Token。具体可以解析请求头中的 Authorization
字段,获取 Token 并进行解密,如果验证成功,则将用户信息添加到请求对象中,并调用 next()
函数,继续执行下一个中间件或路由处理函数。在文件上传接口中,我们使用 verifyToken
中间件进行身份验证。
到此,我们就实现了如何使用 Node.js 在文件上传中添加身份验证的功能,具体可以参考上述代码实现。如果您有任何问题或建议,请在评论区留言。