[英]How to check user credentials before registering a user while also uploading an image to aws s3
I am trying to implement a registration route in my application.我正在尝试在我的应用程序中实施注册路线。 The flow is pretty simple.
流程非常简单。 While using the application, the user has the opportunity to select a profile image (but he doesn't have to).
在使用应用程序时,用户有机会选择个人资料图片(但他没有必要这样做)。 Later on, the user is asked to register and enters an email.
稍后,要求用户注册并输入电子邮件。
Now, I would like to check on my registration route IF the email already exists BEFORE uploading the image to my S3 bucket.现在,在将图像上传到我的 S3 存储桶之前,如果电子邮件已经存在,我想检查我的注册路线。 If it does exist, I want to send back a proper error message.
如果确实存在,我想发回正确的错误消息。 If it does NOT exist, I would like to check if the user has send along an image and proceed to upload the image to S3 so I can store the link in my db and proceed to register the user.
如果它不存在,我想检查用户是否已发送图像并继续将图像上传到 S3,以便我可以将链接存储在我的数据库中并继续注册用户。
The Problem问题
Im appending both the file and the email to a formData object like so.我将文件和电子邮件都附加到这样的 formData 对象中。 At this point the
file
can be empty.此时
file
可以为空。 That depends if the user has selected a profile image or not.这取决于用户是否选择了个人资料图片。
const formData = new FormData();
formData.append('avatar', this.variables.avatar);
formData.append('email', JSON.stringify(this.email));
The problem is that when making the request, either req.file
is undefined or req.body.email
is undefined.的问题是,在进行请求时,无论是
req.file
是未定义或req.body.email
未定义。 The reason for this is simple, I cannot acces the req.body.email
BEFORE the image is uploaded to my s3 bucket.原因很简单,在图像上传到我的 s3 存储桶之前,我无法访问
req.body.email
。 This would mean that everytime a user registers with an already existing email, the image gets send to my s3 bucket nonetheless.这意味着每次用户使用现有电子邮件注册时,图像仍会发送到我的 s3 存储桶。
This is my function to upload to aws:这是我上传到 aws 的功能:
const avatarImgUpload = multer({
storage: multerS3({
s3: s3,
bucket: process.env.AWS_BUCKET,
acl: 'public-read',
key: function (req, file, cb) {
cb(null, path.basename(file.originalname, path.extname(file.originalname)) + '-' + Date.now() + path.extname(file.originalname))
}
}),
}).single('avatar');
And this is my register route:这是我的注册路线:
router.post('/register', (req, res) => {
//let email = JSON.parse(req.body.email);
//The email is undefined because I am not using middleware
//like multer to be able to 'read' or 'acces' this
//Ideally I would like to FIRST check if a user exists like so:
//User.findOne({email: req.body.email})
//If it does not exists, great! Continue to the 'avatarImgUpload' function that uploads to S3'
//If not, send back an error message and end the request there.
avatarImgUpload(req, res, (error) => {
//Within this function I do have access to req.body.email because it uses multer.
//However, like I said before this means that the check IF the user already exists
//has to take place AFTER the image is uploaded to my S3 bucket, which isn't great.
})
})
Is there a way around this?有没有解决的办法? Can I get acces to
req.body.email
BEFORE uploading the image to my S3 bucket?在将图像上传到我的 S3 存储桶之前,我可以访问
req.body.email
吗? Is there a way for example to maybe both send a formData
object AND JSON
so I can first check the email before continuing with the file upload?例如,有没有办法同时发送一个
formData
对象和JSON
这样我就可以在继续上传文件之前先检查电子邮件?
Just split it into 2 requests, let user thinks it's just 1 operation using AJAX:只需将其拆分为 2 个请求,让用户认为它只是使用 AJAX 的 1 个操作:
For more secure, Presigned Url works well.为了更安全,预签名网址效果很好。 Signed url is like a temporary link with temporary permission used to upload to your S3, without this link, user cannot upload to your S3.
签名 url 就像一个临时链接,用于上传到您的 S3 的临时权限,没有此链接,用户无法上传到您的 S3。 Basically, the flow will be:
基本上,流程将是:
Not sure as if multer supports getting signed url, this code is using aws sdk:不确定 multer 是否支持获取签名的 url,此代码使用的是 aws sdk:
router.post('/register', (req, res) => {
// Check User exists
// ...
// Set custom info for the uploading image
const fileName = uuid();
const s3 = new S3();
const params = {
Bucket: 'bucket name',
Key: 'file name',
ContentType: 'image/*',
Expires: 60 * 10, // Url is available for 10 mins
Metadata: {
'email': 'user@example.com',
'custom-field': 'custom data',
},
};
res.send(await s3.getSignedUrl('putObject', params));
});
More info:更多信息:
https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html . https://docs.aws.amazon.com/AmazonS3/latest/dev/PresignedUrlUploadObject.html 。 https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/S3.html#getSignedUrl-property
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.