通过身份验证从动态内容提供者加载 html5 音频

Posted

技术标签:

【中文标题】通过身份验证从动态内容提供者加载 html5 音频【英文标题】:load html5 audio from dynamic content provider with authentication 【发布时间】:2018-06-24 22:28:31 【问题描述】:

假设我们在这里有一个内容提供者端点myuri.org/api/auth/sources/id 它返回由 id 标识的音乐文件。

路由/api/auth/ 需要身份验证。在这种情况下,这是通过在请求标头中传递的 JWT 完成的,例如 Authentication: Bearer <token>

如果不存在身份验证,我可以只加载一个 html5 音频组件,其中包含一个 id 37 的虚构音乐文件的源代码,就像这样

<audio controls>
  <source src="myuri.org/api/sources/37" type="audio/mp3">
</audio>

但是因为我需要认证;这将如何工作?对于提供的任何可能的解决方案;寻找/跳过仍然有效吗?

【问题讨论】:

【参考方案1】:

.. 我花了一些时间寻找其他答案并找到了this post。我想这是不可能的。

替代解决方案

以下代码是遵循所描述逻辑的概念证明。但它没有使用 html5 音频组件,而是使用了Web Audio Api。

let url = "myuri.org/auth/sources/37";

// create context
let audioCtx = new (window.AudioContext || window.webkitAudioContext)();

// create source
let source = audioCtx.createBufferSource();

// route source
source.connect(audioCtx.destination);

// prepare request
let request = new XMLHttpRequest();
request.open('GET', url, true /* async */ );
request.responseType = 'arraybuffer';

request.onload = function () 
    // on load callback

    // get audio data
    let audioData = request.response;

    // try to decode audio data
    audioCtx.decodeAudioData(audioData,
        function (buffer) 
            // on success callback
            console.log("Successfully decoded");

            // set source
            source.buffer = buffer;

            // .. do whatever you want with the source
            // e.g. play it
            source.start(0);
            // or stop
            source.stop();
        ,
        function (e) 
            // on error callback
            console.log("An error occurred");
            console.log(e);
        );
;

request.setRequestHeader("Authorization", `Bearer $authenticationToken`);
request.send();

我希望这对某人有所帮助。

【讨论】:

【参考方案2】:

1

或者,如果您可以更改后端,则可以使其从查询字符串中读取 jwt:

https://myuri.org/api/sources/37?jwt=jwt

在我的例子中,它是 Django(Rest Framework)

# auth.py
from rest_framework_jwt.authentication import JSONWebTokenAuthentication

class QSJSONWebTokenAuthentication(JSONWebTokenAuthentication):
    def get_jwt_value(self, request):
        return request.query_params.get('jwt', '')

# views.py
class AudioView(generics.RetrieveAPIView):
    authentication_classes = (QSJSONWebTokenAuthentication,)

    def retrieve(self, request: Request, *args, **kwargs):
        pass

2

另一种策略也取决于您是否可以控制后端:

向服务器发送请求并请求文件的临时 url,在 &lt;audio&gt; 中使用该 url。诸如 Google Storage 或 S3 之类的存储提供程序具有允许生成 url 的 API,每个人都可以通过该 url 在短时间内访问该文件。您也可以使用 JWT 自己实现类似的东西(一个令牌用于第一个请求中的身份验证,第二个令牌用于文件访问验证)

【讨论】:

我想到了这个,但这不是一个安全问题,因为链接可能记录在某个地方吗? 如果您担心安全性,那么您不应该使用 JWT(:它确实可以登录到拥有 myuri.org 的服务器上,但黑客需要先闯入该服务器,如果他们这样做那么泄露的令牌将不是这里最大的问题。而且每个 JWT 都应该有 time-to-live 参数并且在客户端经常刷新,所以没有人可以使用旧令牌。

以上是关于通过身份验证从动态内容提供者加载 html5 音频的主要内容,如果未能解决你的问题,请参考以下文章

在 SAFARI 中使用带有表单身份验证的 HTML5 音频

如何在点击时动态加载/播放/暂停多源 HTML5 音频?

如何在 HTML 5 中播放经过身份验证的音频流?

UIWebview 不会通过基本身份验证加载动态加载的资源(通过 jQuery 移动)

音频的使用和插入以及动态文字的使用

Android不从间隔播放html5音频