1

I'm building a site that provides paid video content, for embedding in customer's own sites. I'm successfully controlling access to the nodes that contain the video content based on purchasable user roles.

Now I need to provide users with an embed code which ideally would only work from their domain. For now I'd be happy just to be able to limit it to specific users.

I have installed the key_auth and restui modules, and I have enabled the 'file' REST resource. I can now access information *about* the file as an anonymous user with the paying subscriber's api key in the query. However I can't access the actual file.

The info I get back is below.

{"fid":[{"value":3}],"uuid":[{"value":"5655ecda-b421-4ab8-aa92-d43c6c0fbfdf"}],"langcode":[{"value":"en"}],"uid":[{"target_id":1,"target_type":"user","target_uuid":"58d862eb-86e9-4ec6-bb33-89bda5c1767a","url":"\/user\/1"}],"filename":[{"value":"file_example_MP4_480_1_5MG.mp4"}],"uri":[{"value":"private:\/\/2022-04\/file_example_MP4_480_1_5MG.mp4","url":"\/system\/files\/2022-04\/file_example_MP4_480_1_5MG.mp4"}],"filemime":[{"value":"video\/mp4"}],"filesize":[{"value":1570024}],"status":[{"value":true}],"created":[{"value":"2022-04-16T15:52:39+00:00","format":"Y-m-d\\TH:i:sP"}],"changed":[{"value":"2022-04-16T15:52:43+00:00","format":"Y-m-d\\TH:i:sP"}]}

How can I get access to the actual video in this way?

6
  • I take that by get access to the actual video you mean getting the video URL. Since you are using a REST API, I also take the request doesn't come from the Drupal site. The video relative path is given in uri.url. To that, you need to add the site URL. For example, if that is http://example.com/drupal, that video URL would be http://example.com/drupal/system/files/2022-04/file_example_MP4_480_1_5MG.mp4. Since the code is making a REST request, it knows the URL to which the request is sent, which also means it can get the missing part in the video path to make it a complete URL.
    – avpaderno
    Commented Apr 17, 2022 at 7:22
  • Or are you asking On the Drupal side, how do I alter the values returned from the REST API to include the absolute video URL?
    – avpaderno
    Commented Apr 17, 2022 at 7:29
  • Alternatively, get access to the actual video just means that accessing the video using its URL from outside Drupal returns a 403 error and you want to know how to avoid that. Since the video is saved as private file, on Drupal side the access to those files is controlled by hook_file_download(). How an implementation of that hook would understand the file is requested by a client that uses REST API to access the information is the "real" question, in this case.
    – avpaderno
    Commented Apr 17, 2022 at 7:37
  • 1
    If the video is going to be embedded on the client site, anyone viewing the video must necessarily have access. You can probably prevent it from being embedded on unauthorised sites, since most browsers will respect content security policy headers, but if the video is being served as a file you can't prevent it being copied and then served on other platforms. Commented Apr 17, 2022 at 12:39
  • 1
    @AlfredArmstrong Yes, having gone to the lengths described in my answer this became apparent. For this reason I'm now looking at using a video hosting platform that provides protection against this, but its been an interesting journey.
    – griz
    Commented Apr 18, 2022 at 12:36

1 Answer 1

0

I had to write a custom module with the following structure: video_resource.info.yml src/Plugin/Deriver/VideoDeriver.php src/Plugin/rest/resource/VideoResource.php

The rest resource and entity deriver are cut-down copies of the EntityResource and EntityDeriver:

\Drupal\rest\Plugin\rest\resource\EntityResource \Drupal\rest\Plugin\Deriver\EntityDeriver

These classes together create a rest resource for every entity type. I set mine to only create a rest resource for the 'File' entity type, with the following code in its get() function:

$filepath = $entity->getFileUri(); $response = new BinaryFileResponse($filepath); return $response;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.