Laravel - 根据用户会话提供文件
Laravel - Serving files based on user session
我想创建一个应用程序,其中包含多个教学 html 和 css 的视频,这样任何用户都可以在经过身份验证后观看任何视频。
对于每个用户,这些视频中的 url 应该与用户会话相关联,以防止用户将视频 url 发送给其他人以(免费)访问。
当用户登录时possible copy
文件将随用户会话删除。
- 当老师上传视频时,视频将与
存储系统。
- 创建文件副本或在数据库中建立关联?
- 我对如何处理这些文件的想法是否正确?
知道怎么做吗?
更好的方法是使用 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'。无论哪种方式都比使用数据库简单一百倍。
我想创建一个应用程序,其中包含多个教学 html 和 css 的视频,这样任何用户都可以在经过身份验证后观看任何视频。
对于每个用户,这些视频中的 url 应该与用户会话相关联,以防止用户将视频 url 发送给其他人以(免费)访问。
当用户登录时possible copy
文件将随用户会话删除。
- 当老师上传视频时,视频将与 存储系统。
- 创建文件副本或在数据库中建立关联?
- 我对如何处理这些文件的想法是否正确?
知道怎么做吗?
更好的方法是使用 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'。无论哪种方式都比使用数据库简单一百倍。