亚马逊推出了Cloudfront signed cookie最近除了签名的网址。
一个类似的问题是关于 signed url .显然支持 signed url in the cloudfront SDK
但是我在 aws python SDK 中找不到此功能的支持。
我怎样才能创建一个签名的 cookie?
最佳答案
我创建了一个 boto 功能请求来添加它,但与此同时我让它与我的 django python 应用程序一起工作。这是我自己生成的简单代码。底部是一个示例 django View 方法,因此您可以看到我如何为包含 Cloudfront 内容的网页设置 cookie。
import time
from boto.cloudfront import CloudFrontConnection
from boto.cloudfront.distribution import Distribution
from config import settings
import logging
from django.template.context import RequestContext
from django.shortcuts import render_to_response
logger = logging.getLogger('boto')
logger.setLevel(logging.CRITICAL) #disable DEBUG logging that's enabled in AWS by default (outside of django)
AWS_ACCESS_KEY="AKABCDE1235ABCDEF22A"#SAMPLE
AWS_SECRET_KEY="a1wd2sD1A/GS8qggkXK1u8kHlh+BiLp0C3nBJ2wW" #SAMPLE
key_pair_id="APKABCDEF123ABCDEFAG" #SAMPLE
DOWNLOAD_DIST_ID = "E1ABCDEF3ABCDE" #SAMPLE replace with the ID of your Cloudfront dist from Cloudfront console
############################################
def generate_signed_cookies(resource,expire_minutes=5):
"""
@resource path to s3 object inside bucket(or a wildcard path,e.g. '/blah/*' or '*')
@expire_minutes how many minutes before we expire these access credentials (within cookie)
return tuple of domain used in resource URL & dict of name=>value cookies
"""
if not resource:
resource = 'images/*'
dist_id = DOWNLOAD_DIST_ID
conn = CloudFrontConnection(AWS_ACCESS_KEY, AWS_SECRET_KEY)
dist = SignedCookiedCloudfrontDistribution(conn,dist_id)
return dist.create_signed_cookies(resource,expire_minutes=expire_minutes)
############################################
class SignedCookiedCloudfrontDistribution():
def __init__(self,connection,download_dist_id,cname=True):
"""
@download_dist_id id of your Cloudfront download distribution
@cname boolean True to use first domain cname, False to use
cloudfront domain name, defaults to cname
which presumably matches your writeable cookies ( .mydomain.com)
"""
self.download_dist = None
self.domain = None
try:
download_dist = connection.get_distribution_info(download_dist_id)
if cname and download_dist.config.cnames:
self.domain = download_dist.config.cnames[0] #use first cname if defined
else:
self.domain = download_dist.domain_name
self.download_dist = download_dist
except Exception, ex:
logging.error(ex)
def get_http_resource_url(self,resource=None,secure=False):
"""
@resource optional path and/or filename to the resource
(e.g. /mydir/somefile.txt);
defaults to wildcard if unset '*'
@secure whether to use https or http protocol for Cloudfront URL - update
to match your distribution settings
return constructed URL
"""
if not resource:
resource = '*'
protocol = "http" if not secure else "https"
http_resource = '%s://%s/%s' % (protocol,self.domain,resource)
return http_resource
def create_signed_cookies(self,resource,expire_minutes=3):
"""
generate the Cloudfront download distirbution signed cookies
@resource path to the file, path, or wildcard pattern to generate policy for
@expire_minutes number of minutes until expiration
return tuple with domain used within policy (so it matches
cookie domain), and dict of cloudfront cookies you
should set in request header
"""
http_resource = self.get_http_resource_url(resource,secure=False) #per-file access #NOTE secure should match security settings of cloudfront distribution
# http_resource = self.get_http_resource_url("somedir/*") #blanket access to all /somedir files inside my bucket
# http_resource = self.get_http_resource_url("*") #blanket access to all files inside my bucket
#generate no-whitespace json policy, then base64 encode & make url safe
policy = Distribution._canned_policy(http_resource,SignedCookiedCloudfrontDistribution.get_expires(expire_minutes))
encoded_policy = Distribution._url_base64_encode(policy)
#assemble the 3 Cloudfront cookies
signature = SignedCookiedCloudfrontDistribution.generate_signature(policy,private_key_file=settings.AMAZON_PRIV_KEY_FILE)
cookies = {
"CloudFront-Policy" :encoded_policy,
"CloudFront-Signature" :signature,
"CloudFront-Key-Pair-Id" :key_pair_id #e.g, APKA..... -> same value you use when you sign URLs with boto distribution.create_signed_url() function
}
return self.domain,cookies
@staticmethod
def get_expires(minutes):
unixTime = time.time() + (minutes * 60)
expires = int(unixTime) #if not converted to int causes Malformed Policy error and has 2 decimals in value
return expires
@staticmethod
def generate_signature(policy,private_key_file=None):
"""
@policy no-whitespace json str (NOT encoded yet)
@private_key_file your .pem file with which to sign the policy
return encoded signature for use in cookie
"""
#sign the policy - code borrowed from Distribution._create_signing_params()
signature = Distribution._sign_string(policy, private_key_file)
#now base64 encode the signature & make URL safe
encoded_signature = Distribution._url_base64_encode(signature)
return encoded_signature
############################################
def sample_django_view_method(request,template="mytemplate.html"):
expireLen = 30 #30 minutes
s3resource = "somepath_in_my_bucket/afile.mp4"
context = {} #variables I'm passing to my html template
response = render_to_response(template, context, context_instance=RequestContext(request))
domain,cookies = generate_signed_cookies(s3resource,expire_minutes=expireLen)
#TROUBLESHOOTING COOKIES:
#NOTE - Cookie Domain must be a domain you control that spans your app & your Cloudfront CNAME
#NOTE - (e.g. if my webapp is www.mydomain.com and my AWS Download Distribution has cname cloud.mydomain.com, cant set cookies from webapp to
# www.mydomain.com or localhost.mydomain.com or cloud.mydomain.com and have them work
# -> instead set cookies to .mydomain.com to work across sub-domains, you can then verify in request headers to CloudFront that these cookies get passed.
# TIP - if you set_cookies from a page with a .mydomain.com suffix, but don't see them get set in Chrome they didn't get set because of permissions - can't set to a diff subdomain or diff base domain
# TIP - if you set_cookies and see them in Chrome but don't see them in request headers to Cloudfront, cookie domain is likely too narrow, need to widen to span subdomains
base_domain = '.mydomain.com'
# NOTE: Sanity check when testing so you can flag any gotchas - I have not fully tested using non-cname urls inside policy vs all possible domains for cookie itself
if not domain.endswith(base_domain):
logger.warn("This likely won't work - your resource permissions use a different domain than your cookies")
for name,value in cookies.items():
response.set_cookie(name,value=value,httponly=True,domain=base_domain)
return response
############################################
if __name__ == '__main__':
domain,cookies = generate_signed_cookies('images/*',expire_minutes=30)
关于我的设置的注意事项:
我使用了 Chrome 网络开发者工具:
我的 AWS 配置
有了上面的 cookie 生成代码后,最棘手的部分是:
关于python - 为 Amazon CloudFront 创建签名 Cookie,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29383373/
出于纯粹的兴趣,我很好奇如何按顺序创建PI,而不是在过程结果之后生成数字,而是让数字在过程本身生成时显示。如果是这种情况,那么数字可以自行产生,我可以对以前看到的数字实现垃圾收集,从而创建一个无限系列。结果只是在Pi系列之后每秒生成一个数字。这是我通过互联网筛选的结果:这是流行的计算机友好算法,类机器算法:defarccot(x,unity)xpow=unity/xn=1sign=1sum=0loopdoterm=xpow/nbreakifterm==0sum+=sign*(xpow/n)xpow/=x*xn+=2sign=-signendsumenddefcalc_pi(digits
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
如何使用RSpec::Core::RakeTask初始化RSpecRake任务?require'rspec/core/rake_task'RSpec::Core::RakeTask.newdo|t|#whatdoIputinhere?endInitialize函数记录在http://rubydoc.info/github/rspec/rspec-core/RSpec/Core/RakeTask#initialize-instance_method没有很好的记录;它只是说:-(RakeTask)initialize(*args,&task_block)AnewinstanceofRake
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?
我正在阅读SandiMetz的POODR,并且遇到了一个我不太了解的编码原则。这是代码:classBicycleattr_reader:size,:chain,:tire_sizedefinitialize(args={})@size=args[:size]||1@chain=args[:chain]||2@tire_size=args[:tire_size]||3post_initialize(args)endendclassMountainBike此代码将为其各自的属性输出1,2,3,4,5。我不明白的是查找方法。当一辆山地自行车被实例化时,因为它没有自己的initialize方法
我正在尝试按0-9和a-z的顺序创建数字和字母列表。我有一组值value_array=['0','1','2','3','4','5','6','7','8','9','a','b','光盘','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','','u','v','w','x','y','z']和一个组合列表的数组,按顺序,这些数字可以产生x个字符,比方说三个list_array=[]和一个当前字母和数字组合的数组(在将它插入列表数组之前我会把它变成一个字符串,]current_combo['0','0','0']
这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Pythonconditionalassignmentoperator对于这样一个简单的问题表示歉意,但是谷歌搜索||=并不是很有帮助;)Python中是否有与Ruby和Perl中的||=语句等效的语句?例如:foo="hey"foo||="what"#assignfooifit'sundefined#fooisstill"hey"bar||="yeah"#baris"yeah"另外,类似这样的东西的通用术语是什么?条件分配是我的第一个猜测,但Wikipediapage跟我想的不太一样。
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht