Larval Vaporで自動的にwww.を付与するハック
あんまりないけど、URL先頭に自動でwww.を付与したい場合。
例)https://sample.com → https://www.sample.com
たとえば、Middlewareで自動的にwww.を付与する処理を記述する。
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* @var array
*/
protected $middleware = [
// ...
\App\Http\Middleware\RedirectToWwwUrl::class,
// ...
];
class RedirectToWwwUrl
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->getHost() === config('app.domain')) {
return new RedirectResponse(str_replace(
$request->getScheme() . '://',
$request->getScheme() . '://www.',
$request->fullUrl()
), 301);
}
return $next($request);
}
}
このようなコードでVaporにデプロイし、アクセスしてみるとERR_TOO_MANY_REDIRECTSとなってしまう。
これは、Vaporの仕様で自動的にwww.を外し、ルートにリダイレクトするという処理が用意されているからだ。
vapor-core/src/Runtime/Http/Middleware/EnsureOnNakedDomain.php
class EnsureOnNakedDomain
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
if (strpos($request->getHost(), 'www.') === 0) {
return new RedirectResponse(Str::replaceFirst(
'www.', '', $request->fullUrl()
), 301);
}
return $next($request);
}
}
解決方法としては、vapor-coreのバージョンをv2.8.2に上げる。すると、config/vapor.phpが追加され、EnsureOnNakedDomainのコードも以下のように変更されている。
<?php
use Illuminate\Support\Str;
return [
/*
|--------------------------------------------------------------------------
| Redirect robots.txt
|--------------------------------------------------------------------------
|
| When this option is enabled, Vapor will redirect requests to the
| robots.txt file to the location in your assets S# bucket or
| Cloudfront distribution.
|
*/
'redirect_robots_txt' => true,
/*
|--------------------------------------------------------------------------
| Redirect www to the root domain
|--------------------------------------------------------------------------
|
| When this option is enabled, Vapor will redirect requests to the
| www subdomain to the root domain. If the option is disabled,
| vapor will redirect the root domain to the www subdomain.
|
*/
'redirect_www' => true,
];
class EnsureOnNakedDomain
{
/**
* Handle the incoming request.
*
* @param \Illuminate\Http\Request $request
* @param callable $next
* @return mixed
*/
public function handle($request, $next)
{
if ('https://'.$request->getHttpHost() === $_ENV['APP_VANITY_URL']) {
return $next($request);
}
if (config('vapor.redirect_to_root') === true &&
strpos($request->getHost(), 'www.') === 0) {
return new RedirectResponse(Str::replaceFirst(
'www.', '', $request->fullUrl()
), 301);
}
if (config('vapor.redirect_to_root') === false &&
strpos($request->getHost(), 'www.') === false) {
return new RedirectResponse(str_replace(
$request->getScheme().'://',
$request->getScheme().'://www.',
$request->fullUrl()
), 301);
}
return $next($request);
}
}
デフォルトでは、'redirect_to_root' => trueに設定されているため、www.が付与されていれば、自動的に除去されてしまう。そこで、'redirect_to_root' => falseにしてやれば、下の分岐に入るためオリジナルでwww.を付与するMiddleware(例ではRedirectToWwwUrl)を作成せずとも、vaporが自動的に行なってくれる。
ふつうに使う分には、これで解決なわけだが、ある特別な場合に問題が発生する。それは、サブドメインを使用する場合だ。
Route::domain(config('app.domain'))->group(function () {
Route::get('/', 'HomeController')->name('home');
// ...
});
Route::domain('sub.' . config('app.domain'))->group(function () {
Route::get('/', 'Sub\HomeController')->name('sub.home');
// ...
});
vapor-coreのコード(EnsureOnNakedDomain)を見れば分かると思うが、①www.を除去する、②www.を付与する、の2パターンしか存在しない。
つまり、sample.comにアクセスした場合は、問題なくwww.sample.comにリダイレクトされるが、sub.sample.comにアクセスした場合は、www.sub.sample.comとなってしまう。
このような問題を回避する方法を紹介しよう。
ここから先は
¥ 1,000
この記事が気に入ったらサポートをしてみませんか?