我的Laravel网站上有以下文件夹。
/存储/资产/媒体
此文件夹可以包含以下信息
/storage/Asset/Media/1/abc.png
/storage/Asset/Media/2/abc.png
此处1或2是文件夹名称。
我有以下代码来保护文件夹,以便没有人可以在没有身份验证的情况下访问该文件夹
Route::group(['middleware' => ['web', 'auth']], function () {
Route::get('/storage/Asset/Media/{ID}/{eded}', array(
'as' => 'Files',
'uses' => 'User\Account\Media\MediaController@DownloadMedia',
));
});
因此,在用户的会话未在浏览器中过期之前,没有人可以访问这些文件。
问题出现在Android中,所以现在没有人可以访问由于Auth Middleware而导致的文件。
有人可以建议这样的方法,可以通过基于令牌的身份验证(通过Android)和使用Auth Controller(通过网站)下载文件吗?
答案 0 :(得分:6)
您不需要在routes.php
中使用任何其他配置,如果您遵循本指南,一切都会正常工作:
最简单的解决方案是创建名为api_token
的列为users
表。然后,当尝试从Android设备访问资源时,只需将?api_token=<token>
添加到您的网址,其中<token>
是api_token
表格中的users
列。
例如:
domain.com/storage/Asset/Media/1/2?api_token=123hello4secret
系统会尝试使用api_token == 123hello4secret
搜索用户记录,因此只需将123hello4secret
放入您的用户api_token
字段。
如果你想知道为什么你应该api_token
作为列名,答案就在这里:https://github.com/laravel/framework/blob/2a38acf7ee2882d831a3b9a1361a710e70ffa31e/src/Illuminate/Auth/TokenGuard.php#L45如果在请求字段中找到,{Laravel将尝试使用api_token
授权你。
此外,您可以使用HTTP标头来使用令牌进行授权:
标题示例:
Authorization: Bearer 123hello4secret
答案 1 :(得分:2)
请注意,默认情况下&#39;存储&#39;无论如何都无法访问文件夹 - 只有&#39; public&#39;文件夹可公开访问。因此,您可以使用任何URL作为文件下载控制器。
您需要两条路线 - 一条用于基于cookie的身份验证(网络用户),另一条用于无状态(令牌)会话:
// URL can be anything you want
Route::get('downloads/{ID}/{eded}', [
'middleware' => ['web', 'auth'],
'as' => 'Files',
'uses' => 'MediaController@DownloadMedia',
]);
// For API tokens, use 'api' guard of Auth middleware
// URL has to be different, too
Route::get('api/downloads/{ID}/{eded}', [
'middleware' => ['auth:api'],
'as' => 'Files',
'uses' => 'MediaController@DownloadMedia',
]);
您还需要在users表中添加一个令牌字段。在您的用户表迁移中添加一行:
$table->string('api_token', 60)->unique();
然后,您需要生成此令牌。如果要使用相同的令牌(无过期或刷新),则可以在创建新用户时生成它。您可以在User类中使用它:
/**
* @return void
*/
public function boot()
{
User::creating(function ($user) {
$user->api_token = str_random(60);
});
}
否则,您可以强制在每次登录尝试时刷新令牌(在AuthController中使用postLogin),也可以使用单独的控制器方法来交换令牌的电子邮件和密码。
答案 2 :(得分:0)
您需要在auth:api
中间件
使用Laravel的API身份验证非常简单。
答案 3 :(得分:0)
您可以将.htaccess文件放在/ storage / Asset / Media
中代码:
<IfModule mod_rewrite.c>
<IfModule mod_negotiation.c>
Options -MultiViews
</IfModule>
RewriteEngine On
# Redirect Trailing Slashes If Not A Folder...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1 [L,R=301]
# Handle Front Controller...
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} .
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
</IfModule>
您可以在php中访问文件,但直接链接到文件将无法正常工作。
答案 4 :(得分:0)
在您的用户表中,设置一个可以为空的列api_token
现在每次用户通过Api登录时,在db中设置此api_token
并将其发送给Api消费者。
现在,在进一步请求时,Api消费者将在请求标头中发回令牌。所以只需配置Authenticate Middleware:
public function handle($request, Closure $next)
{
if(!empty($request->header('Auth-Token'))) {
$api_token = $request->header('Auth-Token');
$user = User::where('api_token', $api_token)->first();
if(is_null($user)) //Unauthorize: write response to return
} elseif ($this->auth->guest()) {
if ($request->ajax()) {
return response('Unauthorized.', 401);
} else {
return redirect()->guest('/');
}
}
return $next($request);
}