web-dev-qa-db-fra.com

Laravel génère une URL https sécurisée à partir de la route

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?

28
Mārtiņš Briedis

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();

7
Mārtiņš Briedis

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 HTTPSserver 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.

53
Ionut Bajescu

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

6
Oni

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).

  1. 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/ )

  2. Dans le panneau Forge, insérez votre clé privée et votre certificat via Sites > your-site > SSL Certificates > Install Existing Certificate

  3. Activer

  4. Dans le panneau CloudFlare, Crypto > SSL, choisissez «Complet» (non strict).

  5. Fait (cela prendra quelques minutes pour que le changement soit propagé)

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. 

5
Aditya

Comme je l'ai mentionné dans une question pertinente , j'ai trouvé 5 façons de générer des URL sécurisées.

  1. 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;
    }
    
  2. Définissez votre variable d'environnement APP_URL à l'aide de https:

    APP_URL=https://example.com
    
  3. Utilisez l'assistant secure_url () (Laravel5.6)

  4. Ajoutez la chaîne suivante à la méthode AppServiceProvider :: boot () (à partir de la version 5.4):

    \Illuminate\Support\Facades\URL::forceScheme('https');
    
  5. 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.

2
Prisacari Dmitrii

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

2
PHPGrandMaster

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 .

2
mixel

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');
    }
 }
1
Joesel T Duazo

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');
0
Engell Mejía

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

:-)

0
79man

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.

0
Benubird