編集
ルート名から安全なURLを生成する方法を実際に見つけることができません。
完全なURLを取得するには、
echo route('my_route_name');
しかし、httpsを含むURLが必要な場合はどうすればよいですか?
実際には、laravelは現在のURLに基づいて生成されるため、urlが安全であるかどうかは気にしません。httpsページの場合、route()
セキュアURLを返します。httpの場合、_http://
_ url
問題は、Laravelは、httpsが有効になっていることを検出しなかったことです。これは、サーバー構成の問題が原因でした。
Request::isSecure();
を呼び出すことで、Laravel=が現在の接続をhttpsとして認識しているかどうかを確認できます。
PDATE:コメントで指摘したように、これを行うより簡単な方法は、4.2-5.3またはURL::forceSchema('https');
のLaravelバージョンのURL::forceScheme('https');
boot
ファイルのAppServiceProvider
メソッドのバージョン5.4以降。
旧回答:
実際には完全に可能であり、それを達成するために必要なコードは1行だけです。
Laravelはそれ自体でSSLの存在をチェックしません。Symfonyに依存します。そして、現在のリクエストが安全であると信じさせるための鍵があります。
問題は、HTTPS
server param
をtrueに設定する必要があり、最も簡単な方法は、boot
のAppServiceProvider
メソッドに次のコードを貼り付けることです。
$this->app['request']->server->set('HTTPS', true);
私の場合、実稼働環境でSSLを強制するだけで、ローカルenvは引き続きhttpで動作するはずです。これは私が本番環境でのみSSLを強制する方法です:
$this->app['request']->server->set('HTTPS', $this->app->environment() != 'local');
ちなみに、これらの用語に注意してください。将来必要になるかもしれません。
これを行う方法は1つしかないと思います。
名前付きルートへの安全なURLを生成するには、ルートをsecure_url
ヘルパー関数。
secure_url(URL::route('your_route_name', [], false));
route
ヘルパー関数は絶対URL(http://
)デフォルトでは、http
であり、希望するhttps
バージョンではありません
Laravel 5.xは、着信接続が安全であることを検出した場合、route()ヘルパーを介して安全なURLを生成します。通常、アプリサーバーとロードバランサー/プロキシ間の接続が安全でない可能性があるため、アプリがロードバランサーまたはプロキシ(Cloudflareなど)の背後に隠れている場合に問題が発生します。
私はLaravel Forge + Cloudflareを使用しています。これは、着信接続が安全であると考えるアプリを有効にするための最も簡単な方法です(他のプロキシについてはわかりません)。
自己署名証明書を生成します( https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrs または http://www.selfsignedcertificate.com/ )
Forgeパネルで、Sites > your-site > SSL Certificates > Install Existing Certificate
を介して秘密鍵と証明書を挿入します。
有効化
CloudFlareパネルでCrypto > SSL
で[完全]を選択します(厳密ではありません)
つまり、クライアントとCloudflare間の接続は、Cloudflare独自のSSLによって保護されます。アプリサーバーとCloudflare間の接続は、生成された証明書を介して保護されます(したがって、アプリは「接続」を安全と見なします)。
同じ原則を他のスタックに適用できます。
関連する質問 で述べたように、安全なURLを生成する5つの方法を見つけました。
安全でないリクエストをすべてhttpsにリダイレクトするようにWebサーバーを設定します。 nginx設定の例:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Httpsを使用して環境変数APP_URL
を設定します。
APP_URL=https://example.com
ヘルパーを使用 secure_url() (Laravel5.6)
AppServiceProvider :: boot()メソッドに次の文字列を追加します(バージョン5.4以降の場合):
\Illuminate\Support\Facades\URL::forceScheme('https');
ルートグループ(Laravel5.6)の暗黙的に設定されたスキーム:
Route::group(['scheme' => 'https'], function () {
// Route::get(...)->name(...);
});
現時点では、この方法は文書化されていませんが、うまく機能しています。
ほとんどの場合、ルートはサイトがロードされた同じスキームで生成される必要があります。 LaravelはリクエストにX-Forwarded-Proto
ヘッダーを使用して、生成されたルートURLで使用するスキームを決定します。サイトがリバースプロキシの背後にある場合は、リバースプロキシIPアドレスを信頼できるプロキシのリストに追加する必要があります。 https://github.com/fideloper/TrustedProxy パッケージはこれを支援します。 included in Laravel 5.5。たとえば、my config/trustedproxy.php
は次のようになります。
<?php
return [
'proxies' => '*',
'headers' => [
]
];
次の構成を持つnginxリバースプロキシで使用します。
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com_access.log;
error_log /var/log/nginx/example.com_error.log;
client_max_body_size 50m;
location / {
proxy_pass http://localhost:8002;
proxy_set_header Host $Host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
if ($scheme != "https") {
return 301 https://$Host$request_uri;
}
}
置換example.com
ドメインで。 SSL証明書は Let's Encrypt with certbot で提供されました。
Secure_urlを使用します。
secure_url(URL::route('your_route_name', [], false));
完全なURLを返さないようにするには、URL :: routeをfalseに設定する必要があります。次に、secure_url関数を使用して、指定されたパスへの完全修飾HTTPS URLを生成します。
UrlGeneratorインターフェースからURL :: routeを使用できます
string route(string $name, mixed $parameters = array(), bool $absolute = true)
Get the URL to a named route.
Parameters
string $name
mixed $parameters
bool $absolute
Return Value
string
https://laravel.com/api/5.4/Illuminate/Contracts/Routing/UrlGenerator.html
On laravel 5.5。* .configファイルのAPP_URLまたはapp.urlにhttpsが含まれているかどうかを確認する機能がAppServiceProviderに既にあるため、.envファイルにhttpsを追加するだけです。
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
\URL::forceRootUrl(\Config::get('app.url'));
if (str_contains(\Config::get('app.url'), 'https://')) {
\URL::forceScheme('https');
}
}
laravel rl()ヘルパーメソッドに関するドキュメントによると。
パスが指定されていない場合、Illuminate\Routing\UrlGeneratorインスタンスが返されます
したがって、次の方法でrlGeneratorクラスのsecureメソッドを使用できます。
echo url()->secure('my_route_name');
Laravel 5.4を使用して、Bladeでフォームアクションとしてルートを生成しようとしたときにこの問題に遭遇しました。その後、secure_url()を見つけました。
{{ secure_url(route('routename', $args)) }}
コードを掘り下げてデバッグログを追加した後、既に絶対URL(スキームを含む)である場合、secure_urlは着信URL引数を変更しないことが最終的にわかりました。
幸い、routeには3番目の引数として絶対フラグがあり、$ absoluteがfalseとして渡された場合は相対URLを返します。
/ a/{id}/bが名前付きルート「a.b」であると仮定します
route('a.b', 1) : will return http://[domain]/a/1/b
route('a.b', 1, false) : will return /a/1/b
私が到着した2つに参加します。
{{ secure_url(route('routename', $args, false)) }}
予想どおりに生成された---(https:// [domain]/routeXXX
:-)
将来の訪問者の参照用:
Secure_url関数は、GETパラメーターを正しく処理しません。そのため、たとえば、GETフィールドを保持したままユーザーがアクセスしたURLを安全なURLに変換する場合、これを使用する必要があります。
secure_url(Request::path()).'?'.http_build_query(Input::all());
特にurl()ではなくpath()の使用に注意してください-完全なURLを指定すると、開始時にhttpが置き換えられず、効果的に使用できなくなります。