我正在使用REST API通过REST API实现从客户端计算机到AmazonS3的直接文件上传,而没有任何服务器端代码。一切正常,但有一件事让我担心。
当我向Amazon S3 RESTAPI发送请求时,我需要对请求进行签名并将签名放入Authentication标头中。要创建签名,我必须使用我的密钥。但是所有事情都是在客户端发生的,因此,可以很容易地从页面源中揭示密钥(即使我混淆/加密了源)。
Authentication
我该如何处理?这是一个问题吗?也许我只能将特定私钥的使用限制为仅来自特定CORS Origin的RESTAPI调用,以及仅PUT和POST方法,或者仅将密钥链接到S3和特定存储桶?可能还有另一种身份验证方法?
“无服务器”解决方案是理想的,但我可以考虑进行一些服务器端处理,而不是将文件上传到服务器,然后再发送到S3。
我认为您想要的是使用POST的基于浏览器的上传。
基本上,您确实需要服务器端代码,但是它所做的只是生成签名的策略。一旦客户端代码具有签名策略,就可以使用POST直接将其上传到S3,而数据不会通过您的服务器。
签名的策略将以如下形式进入您的html:
<html> <head> ... <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> ... </head> <body> ... <form action="http://johnsmith.s3.amazonaws.com/" method="post" enctype="multipart/form-data"> Key to upload: <input type="input" name="key" value="user/eric/" /><br /> <input type="hidden" name="acl" value="public-read" /> <input type="hidden" name="success_action_redirect" value="http://johnsmith.s3.amazonaws.com/successful_upload.html" /> Content-Type: <input type="input" name="Content-Type" value="image/jpeg" /><br /> <input type="hidden" name="x-amz-meta-uuid" value="14365123651274" /> Tags for File: <input type="input" name="x-amz-meta-tag" value="" /><br /> <input type="hidden" name="AWSAccessKeyId" value="AKIAIOSFODNN7EXAMPLE" /> <input type="hidden" name="Policy" value="POLICY" /> <input type="hidden" name="Signature" value="SIGNATURE" /> File: <input type="file" name="file" /> <br /> <!-- The elements after this will be ignored --> <input type="submit" name="submit" value="Upload to Amazon S3" /> </form> ... </html>
请注意,FORM操作将文件 直接 发送 到S3- 而不是通过服务器。
每当您的一个用户要上传文件时,您都需要在服务器上创建POLICY和SIGNATURE。您将页面返回到用户的浏览器。然后,用户无需通过服务器即可直接将文件上传到S3。
POLICY
SIGNATURE
在签署策略时,通常会使策略在几分钟后过期。这将迫使您的用户在上传之前先与您的服务器对话。这使您可以根据需要监视和限制上传。
进出服务器的唯一数据是签名URL。您的秘密密钥在服务器上保持秘密。