具有django身份验证的跨域媒体
django-crossdomainmedia的Python项目详细描述
具有django身份验证的跨域媒体
这种情况:您提供的媒体文件来自与您的主web应用程序域不同的域(好主意)。要使用nginx's internal redirect (^{
问题:您没有访问媒体域上用户会话的权限,无法对媒体访问进行身份验证或授权。
解决方案:使用附加的过期令牌处理中间url,该令牌临时授权访问,并可在需要时通过重定向刷新。
http视图
下面是它在http中的工作原理:
- ->;获取media.example.org/path/file.pdf
- <;-302www.example.com/path/file.pdf
- ->;获取www.example.com/path/file.pdf
- 如果未授权<;-403
- 如果授权<;-302 media.example.org/path/file.pdf?令牌=xyz
- ->;获取media.example.org/path/file.pdf?令牌=xyz
- <;-200文件.pdf
- 过期后获取media.example.org/path/file.pdf?令牌=xyz
- 参见步骤2
在Django中使用
# DevelopmentMEDIA_URL='/media/'# ProductionMEDIA_URL='https://media.example.org/media/INTERNAL_MEDIA_PREFIX='/protected/'
fromcrossdomainmediaimport(CrossDomainMediaAuth,CrossDomainMediaMixin)classCustomCrossDomainMediaAuth(CrossDomainMediaAuth):''' Create your own custom CrossDomainMediaAuth class and implement at least these methods '''SITE_URL='https://www.example.com'defis_media_public(self):''' Determine if the media described by self.context needs authentication/authorization at all '''returnself.context['object'].is_publicdefget_auth_url(self):''' Give URL path to authenticating view for the media described in context '''obj=self.context['object']raisereverse('view-name',kwargs={'pk':obj.pk})defget_media_file_path(self):''' Return the file path relative to MEDIA_ROOT '''obj=self.context['object']returnobj.file.nameclassCustomDetailView(CrossDomainMediaMixin,DetailView):''' Add the CrossDomainMediaMixin and set your custom media_auth_class '''media_auth_class=CustomCrossDomainMediaAuth
其他一些有用的方法
# Get your media URLs with token outside of viewmauth=CustomCrossDomainMediaAuth({'object':obj})mauth.get_full_media_url(authorized=True)# Send file via nginx internal redirect responsemauth.send_internal_file()
nginx配置
这就是nginx配置的样子。
server{# Web server with session on domainlisten443sslhttp2;server_namewww.example.com;# ...location/{proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Protohttps;proxy_set_headerHost$host;# etc...proxy_passwsgi_server;}}server{# Media server with no session on domainlisten443sslhttp2;server_namemedia.example.org;# ...location/media/{proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Protohttps;proxy_set_headerHost$host;# etc...proxy_passwsgi_server;}location/protected{internal;alias/var/www/media-root;}}