bounty将在2天后过期。回答此问题可获得+500声望奖励。farjam希望引起更多人关注此问题。
我尝试在我的Laravel 9应用程序中上传一个文件。在本地主机上,它运行得很好,但是,当我尝试在Amazon Linux EC2上运行我的应用程序时,同样的操作失败了。
我所知道的
- 这个动作不会抛出任何异常,它只会收到一个HTTP 403错误。(我已经在我的
.env
中启用了调试) - 我只在尝试上传图像的地方收到这个错误。其他控制器工作正常。
我怀疑问题是: - 我认为问题出在Apache/服务器配置上。我在
update()
函数的第一行添加了一个dd()
调用,但它甚至没有到达那里。在此之前抛出了403
错误。见下文。
我为排除故障所做的工作: - 已确保S3存储桶策略正常(同一控制器在本地主机上工作正常)
- 已确保文件权限正常(请参见下面的屏幕截图)
- 确保request类中的
authorize()
函数返回true
- 我查看了错误日志,也没有发现任何相关内容。
- 已确保
php.ini
中包含file_uploads = On
、upload_max_filesize = 4M
和max_file_uploads = 20
我的控制器如下所示(UpdateContactRequest
中的authorize()
函数返回true
):
//https://myapp.com/contacts/1
//App\Http\Controllers\ContactController
public function update(UpdateContactRequest $request, Contact $contact)
{
dd($request); //This does not get executed. The 403 error happens before reaching this.
$contact->update($request->all());
$this->uploadAvatar($request, $contact);
Flash::success('Contact updated successfully.');
return redirect(route('dealers.contacts.index', $contact->dealer->id));
}
下面是我用来上传的uploadAvatar
函数:
private function uploadAvatar(Request $request, Contact $contact)
{
if ($request->hasFile('avatar')) {
try {
$contact
->addMediaFromRequest('avatar')
->sanitizingFileName(function ($fileName) {
return strtolower(str_replace(['#', '/', '\\', ' '], '-', $fileName));
})
->toMediaCollection('avatars');
} catch (\Spatie\MediaLibrary\MediaCollections\Exceptions\FileUnacceptableForCollection $e) {
Flash::error($e->getMessage());
}
}
}
如何定义路由:
Route::get('/', function () {
return view('welcome');
});
Route::get('/test', App\Http\Controllers\TestController::class);
Route::get('/embed-iframe/{uuid}', [App\Http\Controllers\EmbedController::class, 'iframe']);
Route::get('/embed-js/{uuid}', [App\Http\Controllers\EmbedController::class, 'js']);
Auth::routes();
Route::middleware('admin')->group(function () {
Route::get('/home', [App\Http\Controllers\HomeController::class, 'index'])->name('home');
Route::resource('dealers', App\Http\Controllers\DealerController::class);
Route::post('refreshDealerCRMData', [App\Http\Controllers\DealerController::class, 'refreshCRMData']);
Route::post('loadCRMView', [App\Http\Controllers\DealerController::class, 'loadCRMView']);
Route::resource('cms', App\Http\Controllers\CmsController::class);
Route::resource('crms', App\Http\Controllers\CrmController::class);
Route::resource('leads', App\Http\Controllers\LeadController::class);
Route::resource('contacts', App\Http\Controllers\ContactController::class);
Route::resource('attachment-categories', App\Http\Controllers\AttachmentCategoryController::class);
Route::resource('CRMAttachments', App\Http\Controllers\CRMAttachmentController::class);
Route::resource('dealers.leads', App\Http\Controllers\DealerLeadController::class)->scoped([
'dealers' => 'dealer.id',
'leads' => 'lead.id',
]);
Route::resource('dealers.contacts', App\Http\Controllers\DealerContactController::class)->scoped([
'dealers' => 'dealer.id',
'contacts' => 'contact.id',
]);
});
下面是我的根目录(/var/www/html
)的屏幕截图:
下面是在/etc/httpd/conf/httpd.conf
中定义的虚拟主机
<VirtualHost *:443>
ServerAdmin user@domain.com
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot /var/www/html/public
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerAdmin user@domain.com
ServerName myapp.com
ServerAlias www.myapp.com
DocumentRoot /var/www/html/public
<Directory /var/www/html>
Options Indexes FollowSymLinks MultiViews
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
以下是我的IAM策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:ListBucket",
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::mybucket",
"arn:aws:s3:::mybucket/*"
]
}
]
}
下面是抛出的确切错误的屏幕截图:
在没有抛出实际异常的情况下,如何进一步解决这个问题?
3条答案
按热度按时间mbskvtky1#
此问题与AWS WAF规则有关,该规则阻止HTTP发布大小超过特定数字。已删除该规则,现在它可以正常工作。
ia2d9nvy2#
对于其他使用AWS遇到神秘的403错误的用户,这里有一个调试这个问题和类似问题的方法。
首先,验证您的请求是否命中了您的应用程序。一个很好的方法是尝试在
AppServiceProvider
中执行dd()
。在这种情况下,它不会返回任何内容,这就是它位于应用程序外部的线索。如果它位于应用程序内部,请使用dd()
通过应用程序继续调试,或者登录Laravel日志。下一步是确保您正在访问服务器-使用AWS时有两种方法。
使用抽样请求视图
AWS对viewing a sample of web requests有一个彻底的演练-这将允许您查看AWS WAF检查过的任何传入请求,以及允许或阻止的请求。
AWS Waf日志
此外,在设置新项目时,我建议始终启用AWS Waf Logs,这样您就可以看到哪个规则是阻止请求的终止规则。
这两种方法应该足以调试此类错误。
6ju8rftf3#
我猜你遇到的403问题是在一个共享主机中发生的.当你用php artisan storage:link创建符号链接时,它包含了storage/app/public文件夹的完整绝对路径.这可能是服务器响应403的原因.
解决方案是创建一个符号链接,其相对路径与项目根类似
ln -s../存储/应用程序/公共公共/存储