基于JWT认证的Google Drive文件上传与权限控制实现求助
Google Drive文件上传与权限配置解决方案
问题背景
需要实现以下功能:
- 前端上传视频、PDF、图片等文件至Google Drive,上传时自动创建对应文件夹
- 为指定的3个邮箱赋予该文件夹的仅查看权限,非指定邮箱无法访问
- 结合JWT登录系统,前端通过解析JWT获取用户邮箱,判断是否具备访问权限,进而展示对应文件
现有代码无法完成权限添加操作,以下是完整解决方案:
用户原有代码
const { google } = require('googleapis'); const googleScope = ['https://www.googleapis.com/auth/drive'] const googleKey = process.env.GOOGLE_KEY; const fs = require('fs') const express = require('express'); const router = express.Router(); const Multer = require("multer"); const authenticateGoogle = () => { const auth = new google.auth.GoogleAuth({ keyFile: __dirname + "/book-375320-56d9bd2b6239.json", scopes: googleScope, }); return auth; }; const multer = Multer({ storage: Multer.diskStorage({ destination: function (req, file, callback) { callback(null, `${__dirname}/fff`); }, filename: function (req, file, callback) { callback(null, file.fieldname + "_" + Date.now() + "_" + file.originalname); }, }), limits: { fileSize: 5 * 1024 * 1024, }, }); const uploadToGoogleDrive = async (file , auth ) => { const fileMetadata = { name: file.originalname, parents: ["1PLzjikkBXnSpBNi7OZxh3-XhEAIji_94"] }; const media = { mimeType: file.mimetype, body: fs.createReadStream(file.path), }; const driveService = google.drive({ version: "v3", auth }); const response = await driveService.files.create({ requestBody: fileMetadata, media: media, fields: "id", }); return response; }; const deleteFile = (filePath) => { fs.unlink(filePath, () => { console.log("file deleted"); }); }; router.post("/uploadGD", multer.single("file") , async (req , res , next ) => { try { if (!req.file) { res.status(400).send("No file uploaded."); return; } const auth = authenticateGoogle(); const response = await uploadToGoogleDrive(req.file, auth); deleteFile(req.file.path); res.status(200).json({ response }); } catch (err) { console.log(err); }}); module.exports = router;
完整修改方案
1. 新增文件夹创建函数
先创建专属文件夹,再将文件上传至该文件夹下,避免文件混乱:
const createFolder = async (folderName, auth) => { const driveService = google.drive({ version: "v3", auth }); const folderMetadata = { name: folderName, mimeType: 'application/vnd.google-apps.folder' }; const response = await driveService.files.create({ requestBody: folderMetadata, fields: 'id' }); return response.data.id; };
2. 新增权限设置函数
为文件夹添加指定邮箱的查看权限,同时移除可能的公开访问权限,确保仅指定用户可访问:
const addFolderPermissions = async (folderId, emails, auth) => { const driveService = google.drive({ version: "v3", auth }); // 移除默认公开权限(可选,确保文件夹私有) const permissions = await driveService.permissions.list({ fileId: folderId, fields: 'permissions(id,type,role)' }); for (const perm of permissions.data.permissions) { if (perm.type === 'anyone' || perm.role === 'writer') { await driveService.permissions.delete({ fileId: folderId, permissionId: perm.id }); } } // 为每个邮箱添加只读权限 for (const email of emails) { await driveService.permissions.create({ fileId: folderId, requestBody: { type: 'user', role: 'reader', emailAddress: email }, fields: 'id' }); } };
3. 修改上传路由逻辑
整合文件夹创建、文件上传、权限配置流程,同时接收前端传来的邮箱列表:
router.post("/uploadGD", multer.single("file"), async (req, res, next) => { try { if (!req.file) { return res.status(400).send("No file uploaded."); } // 获取前端传来的授权邮箱列表 const { emails } = req.body; if (!emails || !Array.isArray(emails) || emails.length === 0) { return res.status(400).send("Please provide at least one authorized email."); } const auth = authenticateGoogle(); // 创建专属文件夹(用时间戳+文件名命名,避免重复) const folderName = `${Date.now()}_${req.file.originalname.split('.')[0]}`; const folderId = await createFolder(folderName, auth); // 上传文件至新建文件夹 const fileMetadata = { name: req.file.originalname, parents: [folderId] }; const media = { mimeType: req.file.mimetype, body: fs.createReadStream(req.file.path), }; const driveService = google.drive({ version: "v3", auth }); const fileResponse = await driveService.files.create({ requestBody: fileMetadata, media: media, fields: "id" }); // 为文件夹设置权限 await addFolderPermissions(folderId, emails, auth); // 删除本地临时文件 deleteFile(req.file.path); // 返回文件夹ID和文件ID,供前端后续处理 res.status(200).json({ folderId, fileId: fileResponse.data.id, authorizedEmails: emails }); } catch (err) { console.error(err); res.status(500).send("Upload failed."); } });
4. 前端JWT权限验证逻辑
前端需完成以下操作:
- 解析JWT获取当前登录用户的邮箱
- 方式一:直接对比上传时返回的
authorizedEmails列表,匹配则展示文件和访问链接 - 方式二:后端存储文件夹ID与授权邮箱的映射(如数据库),前端请求文件列表时携带JWT,后端解析邮箱后查询权限,返回可访问的文件资源
注意事项
- 确保Google Cloud服务账号具备Google Drive API权限,且服务账号邮箱已被共享至Google Drive的根目录或父文件夹
- 权限设置时,需验证前端传来的邮箱格式有效性,避免无效权限配置
- 若需支持多文件上传,可将
multer.single("file")改为multer.array("files", 10),并调整上传逻辑批量处理文件
内容的提问来源于stack exchange,提问作者gnar999
相关产品推荐
相关产品推荐

