Search code examples
vue.jsauthenticationvideo-streaminghtml5-videovideo.js

Add authentication headers to native video element


I am using videojs-player for Vue in order to display videos fetched from my backend application.

I use Django REST Framework (DRF) on the backend (server-side) and a Vue SPA on the frontend. My app achieves authentication by obtaining a token at login time; axios sends that login as an authorization header in every subsequent requests made by the frontend

Problem:
One problem I'm facing is that authentication is required in order to access the videos on the backend; which is achieved application-wide by using a bearer token authentication header.

videojs-player internally uses a native <video> element, which just takes a src url and makes a request to get the video.

This of course results in a 401 response as no authentication is provided.

Is there a way to inject the appropriate header in this situation?


Solution

  • Note: This current method (of client-side accessing the file) means you have to wait for the file to fully download before you can play it. Unless you know how make Axios "stream" a file (packet by packet)?.

    The best solution would be to actually do the file reading part using a server-side script (eg: a PHP script). This means after being logged-in and getting the token, you pass that token and expected file name as a URL variable. The request URL points to a script file which has instructions to check if provided token is valid and then return the mentioned video file.

    pseudo-code JS example: video.src="myScriptFile?token=XXXX&file=video1.mp4"

    Without using any server-side scripts:

    Below is a code example to load video data from Axios into a video tag.
    For testing, modify the file paths to use your own (or just test at: W3Schools Editor).

    <!DOCTYPE html>
    <html>
    <body>
    
    <video id="myvid" width="640" height="400" controls>
    <source src="null.mp4" type="video/mp4">
    </video>
    
    <script src="https://unpkg.com/axios/dist/axios.min.js"> </script>
    
    <script>
    
    var path; var vid_1; var vid_2;
    var myvid = document.getElementById("myvid");
    
    //# testing file paths
    vid_1 = "https://www.w3schools.com/html/mov_bbb.mp4"
    vid_2 = "https://www.w3schools.com/html/movie.mp4";
    
    //# test axios function with some file path
    getvideo( vid_1 );
    
    function getvideo ( input_filepath )
    {
        axios.request(
        {
          responseType: 'blob',
          url: input_filepath,
          method: 'get',
          headers: {
                        'Content-Type': 'video/mp4',
                        'Token': 'your_token_here'
                    }
        }).then( 
                    (result) => {
                                    //alert( "data : " + result.data );
                                    path = (window.URL || window.webkitURL).createObjectURL( result.data);
                                    myvid.src = path;
                                    myvid.load(); 
                                    //myvid.play();
                                }
        );
        
        //# do anything else here...???
        
        
    }
    
    </script>
    
    </body>
    </html>