- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 Meteor Mobile 应用程序,可以访问我的 S3 存储桶中存储的大量照片。这些照片是用户上传的并且经常更改。我不希望不使用我的应用程序的任何人都可以访问这些照片。 (即:这些照片只能从我的应用程序中查看,直接在浏览器中访问网址不会加载它们)。
实现这一目标的最佳方法是什么? AWS Cognito 似乎是合乎逻辑的选择,但实现起来似乎并不容易,而且我不太确定客户端获得 Cognito 身份后如何向 AWS 进行身份验证。
我的另一个想法是在每个 URL 上放置一个只读 AWS key 并以这种方式进行身份验证,但这几乎毫无意义。找出 key 和 secret 真的很容易。
编辑:
具体来说,图像的 URL 位于 Mongo 集合中,我将它们传递到模板中。因此,S3 资源只是加载了图像标签 ( <img src="
)。像 AWS STS 这样的东西听起来是一个不错的选择,但是当我像这样加载它们时,我不知道如何在 header 中传递 token 。将它们作为预签名查询字符串来执行似乎效率很低。
另一个选项是使用 referrer
限制访问 header ,like this issue 。但正如 Martijn 所说,这并不是一种真正安全的方法。
最佳答案
经过一些研究和测试,我自己解决了这个问题。我的最终解决方案是使用 referer
header 来限制对我的 S3 存储桶的访问。我创建了一个更安全、更详细的解决方案(见下文),但它带来了性能损失,不适用于我的应用程序。我的应用程序基于查看照片和视频,不可能立即加载它们。尽管如此,我觉得它对于大多数用例来说可能是一个足够的解决方案。由于我的应用不是高度敏感,因此 referer
header 对我来说就足够了。 Here is how to use the http header referer
to limit access to a bucket.
使用亚马逊 STS 的解决方案:
首先,您需要在 server 上都拥有 AWS 开发工具包。和 client.没有可用的 Meteor 的最新软件包,因此我创建了自己的软件包。 (我将很快发布它,并在发布后在此处放置一个链接。)
在服务器上,您必须使用能够承担 Angular 色的凭据。要担任的 Angular 色必须与担任该 Angular 色的用户具有信任关系。 Article on using IAM. -Article on using credentials with SDK
在 server.js
文件中,我创建了一个可以从客户端调用的 Meteor 方法。它首先检查用户是否登录。如果是,它会检查当前的临时凭证是否在接下来的 5 分钟内到期。如果是,我会发出新的凭据,并将它们写入用户文档或作为回调返回。如果它们在接下来的 5 分钟内没有过期,我将返回他们当前的临时凭证。
您必须使用 Meteor.bindEnvironment
进行回调。 See docs
Meteor.methods({
'awsKey': function(){
if (Meteor.userId()){
var user = Meteor.userId();
var now = moment(new Date());
var userDoc = Meteor.users.findOne({_id: user});
var expire = moment(userDoc.aws.expiration);
var fiveMinutes = 5 * 60 * 1000;
var fut = new Future();
if(moment.duration(expire.diff(now))._milliseconds < fiveMinutes ){
var params = {
RoleArn: 'arn:aws:iam::556754141176:role/RoleToAssume',
RoleSessionName: 'SessionName',
DurationSeconds: 3600 //1 Hour
};
var sts = new AWS.STS();
sts.assumeRole(params, Meteor.bindEnvironment((err, data) => {
if (err){
fut.throw(new Error(err));
}else{
Meteor.users.update({_id: user}, {$set: {aws: {accessKey: data.Credentials.AccessKeyId, secretKey: data.Credentials.SecretAccessKey, sessionToken: data.Credentials.SessionToken, expiration: data.Credentials.Expiration}}});
fut.return(data.Credentials);
}
}));
return fut.wait();
}else{
return userDoc.aws;
}
}
}
}
});
然后您可以手动调用此方法,也可以在 Meteor.startup
上的 setInterval
中调用此方法。
Meteor.setInterval(function(){
if(Meteor.userId()){
Meteor.call('awsKey', function(err, data){
if (err){
console.log(err);
}else{
if(data.accessKey){
Session.set('accessKey', data.accessKey);
Session.set('secretKey', data.secretKey);
Session.set('sessionToken', data.sessionToken);
}else{
Session.set('accessKey', data.AccessKeyId);
Session.set('secretKey', data.SecretAccessKey);
Session.set('sessionToken', data.SessionToken);
}
}
});
}
}, 300000); //5 Minute interval
这种方式只是从回调中设置 session 变量中的键。您也可以通过查询用户的文档来获取它们来完成此操作。
然后,您可以使用这些临时凭据来获取您尝试在存储桶中访问的对象的签名 URL。
我通过在模板中将对象名称传递给它来将其放入模板助手中:
{{getAwsUrl imageName}}
Template.templateName.helpers({
'getAwsUrl': function(filename){
var accessKey = Session.get('accessKey');
var secretKey = Session.get('secretKey');
var sessionToken = Session.get('sessionToken');
var filename = filename;
var params = {Bucket: 'bucketName', Key: filename, Expires: 6000};
new AWS.S3({accessKeyId: accessKey, secretAccessKey: secretKey, sessionToken: sessionToken, region: 'us-west-2'}).getSignedUrl('getObject', params, function (err, url) {
if (err) {
console.log("Error:" +err);
}else{
result = url;
}
});
return result;
}
});
这就是全部内容了!我确信这可以改进得更好,但这只是我在快速测试时想到的。就像我说的,它应该适用于大多数用例。我的那个没有。由于某种原因,当您尝试在这些签名 URL 的 img src
上切换 visibility:visible|hidden;
时,它们的加载时间将比仅设置 URL 花费的时间长得多直接地。这肯定是因为亚马逊必须在返回对象之前解密其签名的 URL。
感谢Mikkel为方向。
关于javascript - 从 Meteor 移动应用程序向 S3 进行身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39757309/
在 JSF2 应用程序中遇到验证属性的问题时,有两种主要方法。 使用 Annotation 在 ManagedBean 上定义验证 @ManagedBean public class MyBean {
我想实现一个不常见的功能,我认为 jquery 验证插件将是最好的方法(如果您在没有插件的情况下建议和回答,我们也会欢迎)。我想在用户在输入字段中输入正确的单词后立即隐藏表单。我试过这个: $("
我有几个下拉菜单(类名为month_dropdown),并且下拉菜单的数量不是恒定的。我怎样才能为它们实现 NotEqual 验证。我正在使用 jQuery 验证插件。 这就是我写的 - jQuery
我设法制作了这个网址验证代码并且它起作用了。但我面临着一个问题。我认为 stackoverflow 是获得解决方案的最佳场所。 function url_followers(){ var url=do
我目前正在使用后端服务,该服务允许用户在客户端应用程序上使用 Google Games 库登录。 用户可以通过他们的 gplay ID 向我们发送信息,以便登录或恢复旧帐户。用户向我们发送以下内容,包
我正在尝试验证输入以查看它是否是有效的 IP 地址(可能是部分地址)。 可接受的输入:172、172.112、172.112.113、172.112.113.114 Not Acceptable 输入
我从 Mongoose 验证中得到这条消息: 'Validator failed for path phone with value ``' 这不应该发生,因为不需要电话。 这是我的模型架构: var
我一直在尝试使用Python-LDAP (版本 2.4.19)在 MacOS X 10.9.5 和 Python 2.7.9 下 我想在调用 .start_tls_s() 后验证与给定 LDAP 服务
我正在处理一个仅与 IE6 兼容的旧 javascript 项目(抱歉...),我想仅在 VS 2017 中禁用此项目的 ESLint/CSLint/Javascript 验证/CSS 验证。 我知道
我正在寻找一种方法来验证 Spring 命令 bean 中的 java.lang.Double 字段的最大值和最小值(一个值必须位于给定的值范围之间),例如, public final class W
我正在尝试在 springfuse(JavaEE 6 + Spring Framework (针对 Jetty、Tomcat、JBoss 等)) 和 maven 的帮助下构建我的 webapps 工作
我试图在我们的项目中使用 scalaz 验证,但遇到了以下情况: def rate(username: String, params: Map[String, String]): Validation
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
我有一个表单,人们可以单击并向表单添加字段,并且我需要让它在单击时验证这些字段中的值。 假设我单击它两次并获取 2 个独立的字段集,我需要旋转 % 以确保它在保存时等于 100。 我已放入此函数以使其
在我的页面中有一个选项可以创建新的日期字段输入框。用户可以根据需要创建尽可能多的“截止日期”和“起始日期”框。就像, 日期_to1 || date_from1 日期到2 ||日期_from2 date
我有一个像这样的 Yaml 文件 name: hhh_aaa_bbb arguments: - !argument name: inputsss des
有没有办法在动态字段上使用 jquery 验证表单。 我想将其设置为必填字段 我正在使用 Jsp 动态创建表单字段。 喜欢 等等...... 我想使用必需的表单字段验证此表单字段。 最佳答
嗨,任何人都可以通过提供 JavaScript 代码来帮助我验证用户名文本框不应包含数字,它只能包含一个字符。 最佳答案 使用正则表达式: (\d)+ 如果找到匹配项,则字符串中就有一个数字。 关于J
我有两个输入字段holidayDate和Description(id=tags) $(document).ready(function() {
我遇到了这个问题,这些验证从电子邮件验证部分开始就停止工作。 我只是不明白为什么即使经过几天的观察,只是想知道是否有人可以在这里指出我的错误? Javascript部分: function valid
我是一名优秀的程序员,十分优秀!