Laravel - 根据用户会话提供文件

Laravel - Serving files based on user session

我想创建一个应用程序,其中包含多个教学 html 和 css 的视频,这样任何用户都可以在经过身份验证后观看任何视频。

对于每个用户,这些视频中的 url 应该与用户会话相关联,以防止用户将视频 url 发送给其他人以(免费)访问。

当用户登录时possible copy文件将随用户会话删除。

  1. 当老师上传视频时,视频将与 存储系统。
  2. 创建文件副本或在数据库中建立关联?
  3. 我对如何处理这些文件的想法是否正确?

知道怎么做吗?

更好的方法是使用 middleware。创建一个 table 来存储哪个用户可以访问哪个视频。中间件可以检查登录的用户是否可以访问所请求的视频。如果不是abort(403).

URL 对所有用户都是一样的,比方说 /videos/{video_id} 但由于中间件的存在,只有被授予访问权限的用户才能观看视频

我会把你的问题分成两部分

  • 使视频内容可分配给经过身份验证的用户
  • 防止所有经过身份验证的用户在当前会话之外共享内容

第一
'many-to-many' 上传内容与用户的关系
users -> video_user <- videos
$user->allowedVideos() & $video->allowedUsers()

第二
您的视频内容应该可以通过安全路径访问

{base_url}/video/{video_id}

正如@jithin 建议的那样,我们可以使用 middleware 来授权用户登录会话并检查用户是否可以访问视频。否则 return 403.

-- 答案已更新

假设您必须对文件实施访问限制。因此,正如@Farooq Khan 所建议的那样,实施一个枢轴 table 来保存 user-file 映射以查找谁有权访问这些文件。

下一步将验证文件 url。文件 url 对所有用户都是相同的,例如 /admin/download/{fileName}。请注意,该文件实际上并不存在于 /admin/download/ 目录中,因此请求将被 Web 服务器重定向到 laravel。

Route::get('/admin/download/{file_name}', ['as' => 'admin.download', function($fileName) 
{
    return Response::download($file_name);
}])->before('file_auth');

现在您必须创建 file_auth 中间件,您必须在其中检查用户 (Auth::user()->id) 是否有权访问文件名 ($request->route('fileName'))。如果用户没有权限响应 403.

假设视频已嵌入,但您也不希望视频 link 从源中提取,我建议您采用基本方法。

如果所有用户都可以访问所有视频,那么在数据库中维护一个映射是个坏主意。那会变得很大,很快。也是un-necessary。

您可以在路线的末尾添加部分,可以这样说;

$router->get('/watch/{videoId}/{userId}', [....]);

然后是类似的东西;

$router->get('/video/{videoId}/{userId}, [....]);

第一个是您观看视频的页面的路径,第二个是您用来嵌入视频的动态 link。您现在需要做的就是添加一些执行以下操作的中间件;

if ($router->param('userId') !== auth()->id()) {
    throw new NotFoundHttpException();
}

或者,您可以执行上述操作,但路线将具有 {videoId}/{videoHash} 而不是 {videoId}/{userId}。视频哈希将类似于以下内容;

$videoHash = crc32($video->id . ';' . auth()->id);

然后,您只有像上面那样的中间件,但它执行以下操作;

$hash = crc32($router->param('videoId') . ';' . auth()->id());
if ($router->param('videoHash') !== $hash) {
    throw new NotFoundHttpException();
}

第二个选项有点过于复杂,但可能 'look a bit better'。无论哪种方式都比使用数据库简单一百倍。