Je ne trouve pas vraiment le moyen de générer une URL sécurisée à partir du nom de la route.
Pour obtenir une URL complète, j'utilise
echo route('my_route_name');
Mais que faire si je veux une URL avec https?
En fait, Laravel ne s’inquiète pas de savoir si l’URL est sécurisée ou non, car elle génère en fonction de l’URL actuelle. Si vous êtes sur la page https, route()
renverra une URL sécurisée. Si sur http, alors http://
url
Le problème était que Laravel n'a pas détecté que https était activé, ce qui était dû à une configuration de serveur défectueuse.
Vous pouvez vérifier si Laravel voit la connexion actuelle comme étant https en appelant Request::isSecure();
UPDATE: Comme indiqué dans les commentaires, il serait plus simple d'ajouter URL::forceSchema('https');
pour la version de Laravel entre 4.2-5.3 ou URL::forceScheme('https');
pour la version 5.4+ dans la méthode boot
de votre fichier AppServiceProvider
.
Ancienne réponse:
En fait, c'est tout à fait possible et une seule ligne de code est nécessaire pour accomplir cela.
Laravel ne vérifie pas la présence de SSL par lui-même, cela dépend de Symfony. Et nous avons la clé pour faire croire que la demande actuelle est sécurisée.
En réalité, nous devons définir la variable HTTPS
server param
sur true et la méthode la plus simple consiste à coller le code suivant dans la méthode boot
de votre AppServiceProvider
:
$this->app['request']->server->set('HTTPS', true);
Dans mon cas même, je dois seulement forcer SSL en production, l’environnement local doit toujours fonctionner sur http. Voici comment je force SSL uniquement en production:
$this->app['request']->server->set('HTTPS', $this->app->environment() != 'local');
À propos, gardez ces termes à l'esprit, vous en aurez peut-être besoin à l'avenir.
Je pense qu'il n'y a qu'une seule façon de faire cela.
Pour générer l'URL sécurisée vers vos itinéraires nommés, vous pouvez transférer votre itinéraire dans la fonction d'assistance secure_url
.
secure_url(URL::route('your_route_name', [], false));
Vous ne pouvez pas vraiment utiliser la fonction d'assistance route
car elle génère une URL absolue (avec http://
) par défaut et que c'est http
et non la version https
que vous vouliez
Laravel 5.x générera une URL sécurisée via l’assistant route () s’il détecte que la connexion entrante est sécurisée. Le problème survient généralement si l'application est masquée derrière un équilibreur de charge ou un proxy (par exemple, Cloudflare), car la connexion entre le serveur d'applications et l'équilibreur de charge/proxy peut ne pas être sécurisée.
J'utilise Laravel Forge + Cloudflare maintenant et c'est le moyen le plus simple que j'ai trouvé pour permettre à l'application de penser que la connexion entrante est sécurisée (je ne suis pas sûr d'un autre proxy).
Générez un certificat auto-signé (voir https://www.digitalocean.com/community/tutorials/openss-essentials-working-with-ssl-certificates-private-keys-and-csrs ou http: // www.selfsignedcertificate.com/ )
Dans le panneau Forge, insérez votre clé privée et votre certificat via Sites > your-site > SSL Certificates > Install Existing Certificate
.
Activer
Dans le panneau CloudFlare, Crypto > SSL
, choisissez «Complet» (non strict).
En bref, la connexion entre le client et Cloudflare est sécurisée par le propre SSL de Cloudflare. La connexion entre le serveur d'applications et Cloudflare est protégée via votre certificat généré (l'application considère donc que la «connexion» est sécurisée.
Vous pouvez appliquer le même principe avec d'autres piles.
Comme je l'ai mentionné dans une question pertinente , j'ai trouvé 5 façons de générer des URL sécurisées.
Configurez votre serveur Web pour rediriger toutes les demandes non sécurisées vers https. Exemple de configuration nginx:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com www.example.com;
return 301 https://example.com$request_uri;
}
Définissez votre variable d'environnement APP_URL
à l'aide de https:
APP_URL=https://example.com
Utilisez l'assistant secure_url () (Laravel5.6)
Ajoutez la chaîne suivante à la méthode AppServiceProvider :: boot () (à partir de la version 5.4):
\Illuminate\Support\Facades\URL::forceScheme('https');
Schéma implicitement défini pour le groupe de routes (Laravel5.6):
Route::group(['scheme' => 'https'], function () {
// Route::get(...)->name(...);
});
Pour le moment, cette méthode n’est pas documentée, mais cela fonctionne bien.
Utilisez secure_url:
secure_url(URL::route('your_route_name', [], false));
Vous devrez définir URL :: route sur false pour ne pas renvoyer une URL complète. Ensuite, utiliser la fonction secure_url génère une URL HTTPS complète pour le chemin indiqué.
Depuis l'interface UrlGenerator, vous pouvez utiliser 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
Dans la plupart des cas, les itinéraires doivent être générés avec le même schéma que celui sur lequel votre site a été chargé. Laravel détecte automatiquement si la requête a un en-tête X-Forwarded-Proto
et l'utilise pour décider du schéma à utiliser dans les URL de route générées. Si votre site est derrière un proxy inverse, vous devez ajouter une adresse IP de proxy inverse à la liste des serveurs proxy approuvés. https://github.com/fideloper/TrustedProxy package aide à faire cela. C'est inclus dans Laravel 5.5. Par exemple, mon config/trustedproxy.php
ressemble à:
<?php
return [
'proxies' => '*',
'headers' => [
]
];
Je l'utilise avec le proxy inverse nginx dont la configuration est la suivante:
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;
}
}
Remplacez example.com
par votre domaine. Les certificats SSL ont été fournis par Encryptons avec certbot .
Sur laravel 5.5. * Il vous suffit d’ajouter https sur votre fichier .envas AppServiceProvider avait déjà une fonction qui vérifie si votre APP_URL ou votre application.url sur votre configuration est doté de la fonctionnalité 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');
}
}
Selon la documentation de laravel sur la méthode url () helper.
Si aucun chemin n'est fourni, l'instance Illuminate\Routing\UrlGenerator est revenu
Vous pouvez donc utiliser la méthode secure de la classe UrlGenerator de la manière suivante:
echo url()->secure('my_route_name');
Je suis tombé sur ce problème en essayant de générer une route sous forme d’action de formulaire dans Blade avec Laravel 5.4 . Puis j’ai tapé sur secure_url (), j’ai donc
{{ secure_url(route('routename', $args)) }}
Cela renvoyait toujours une URL non sécurisée. :-(
Après avoir fouillé dans le code et ajouté des journaux de débogage, j'ai finalement compris que secure_url ne modifiait pas l'argument des URL entrantes, s'il s'agissait déjà d'une URL absolue (y compris le schéma).
Heureusement, route a un indicateur absolu comme troisième argument et renvoie une URL relative si $ absolute est passé en tant que false.
En supposant que/a/{id}/b est une route nommée "a.b"
route('a.b', 1) : will return http://[domain]/a/1/b
route('a.b', 1, false) : will return /a/1/b
En rejoignant les deux je suis arrivé à:
{{ secure_url(route('routename', $args, false)) }}
Comme prévu, il a généré https: // [domaine]/routeXXX
:-)
Pour référence des futurs visiteurs:
La fonction secure_url ne gère pas correctement les paramètres GET. Ainsi, par exemple, si vous souhaitez convertir l'URL que l'utilisateur a visitée en une URL sécurisée tout en conservant les champs GET, vous devez utiliser ceci:
secure_url(Request::path()).'?'.http_build_query(Input::all());
Notez en particulier l’utilisation de path () plutôt que d’url () - si vous lui donnez une URL complète, elle ne remplacera pas le http au début, le rendant ainsi inutilisable.