Amazon web services AWS S3预签名URL因Amplify上的短身份验证令牌过期而过期
我有一个ReactJs应用程序,它从API检索一个S3URL,并使用Amazon web services AWS S3预签名URL因Amplify上的短身份验证令牌过期而过期,amazon-web-services,amazon-s3,aws-amplify,pre-signed-url,amplifyjs,Amazon Web Services,Amazon S3,Aws Amplify,Pre Signed Url,Amplifyjs,我有一个ReactJs应用程序,它从API检索一个S3URL,并使用Amplify Storage库获取它的预签名版本 此URL是视频源,代码如下: Storage.get( outputVideoSrc, { expires: 43200 } )); 但我注意到,即使过期时间很长,约1小时后视频停止播放,显示网络错误消息并中止播放 如果我获取视频URL并尝试从浏览器访问它,我会看到类似的错误: &l
Amplify Storage
库获取它的预签名版本
此URL是视频源,代码如下:
Storage.get(
outputVideoSrc,
{ expires: 43200 }
));
但我注意到,即使过期时间很长,约1小时后视频停止播放,显示网络错误消息并中止播放
如果我获取视频URL并尝试从浏览器访问它,我会看到类似的错误:
<Error>
<Code>ExpiredToken</Code>
<Message>The provided token has expired.</Message>
<Token-0>
...
通过谷歌搜索,我发现这个过期是由于身份验证令牌过期,而不是预签名URL本身。
然而,我需要这个URL工作超过1小时,所以用户可以与视频工作很长一段时间
似乎无法自定义令牌在Amplify上的持续时间:
我还试图在一段时间后继续重新加载视频,希望得到一个刷新的令牌,但是:
我有哪些备选方案可以使这项工作正常进行,而不让视频一直停止播放?我发现解决这一问题的唯一方法是使用lambda函数对URL进行预签名,并使用它解析我架构上的GraphQL字段 因此,在使用
amplify cli
时,我添加了一个新函数
放大函数加法
在这里的示例中,我将其命名为geturl
My function的代码与此类似:
import boto3
from botocore.exceptions import ClientError
s3_client = boto3.client('s3')
bucket = 'my-bucket'
def handler(event, context):
print('received event:')
print(event)
urls = []
if 'typeName' in event and event['typeName'] == 'MyType' and event['fieldName'] == 'urls':
print('Requesting field keys for MyType...', event['source']['keys'])
for key in event['source']['keys']:
try:
signed_url = s3_client.generate_presigned_url(
'get_object',
Params={
'Bucket': bucket,
'Key': key,
},
ExpiresIn=86400 # 24 hours
)
print('Signed URL: ', signed_url)
if signed_url:
urls.append(signed_url)
except ClientError as e:
print('Error', e)
return urls
不要忘记为您的函数在bucket上的S3:GetObject
添加权限
在getURL CloudOfFormation template.json上
在您的保单文档中添加:
{
"Sid": "S3",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
}
然后将其添加为schema.graphql上字段的解析程序
type MyType @model
{
id: ID!
keys: [String!]
urls [String!] @function(name: "getUrls-${env}")
}
也就是说,当您请求字段url
时,它将返回有效期为24小时的预签名url,然后您可以将其更改为所需的任何持续时间。我发现解决此问题的唯一方法是使用lambda函数对url进行预签名,并使用它解析我架构上的GraphQL字段
因此,在使用amplify cli
时,我添加了一个新函数
放大函数加法
在这里的示例中,我将其命名为geturl
My function的代码与此类似:
import boto3
from botocore.exceptions import ClientError
s3_client = boto3.client('s3')
bucket = 'my-bucket'
def handler(event, context):
print('received event:')
print(event)
urls = []
if 'typeName' in event and event['typeName'] == 'MyType' and event['fieldName'] == 'urls':
print('Requesting field keys for MyType...', event['source']['keys'])
for key in event['source']['keys']:
try:
signed_url = s3_client.generate_presigned_url(
'get_object',
Params={
'Bucket': bucket,
'Key': key,
},
ExpiresIn=86400 # 24 hours
)
print('Signed URL: ', signed_url)
if signed_url:
urls.append(signed_url)
except ClientError as e:
print('Error', e)
return urls
不要忘记为您的函数在bucket上的S3:GetObject
添加权限
在getURL CloudOfFormation template.json上
在您的保单文档中添加:
{
"Sid": "S3",
"Effect": "Allow",
"Action": [
"s3:GetObject"
],
"Resource": "arn:aws:s3:::mybucket/*"
}
然后将其添加为schema.graphql上字段的解析程序
type MyType @model
{
id: ID!
keys: [String!]
urls [String!] @function(name: "getUrls-${env}")
}
也就是说,当您请求字段url
时,它将返回有效期为24小时的预签名url,然后您可以将其更改为您想要的任何持续时间