Laravel从路由生成安全的https URL

Mār*_*dis 33 url https routing laravel

我真的找不到从路由名称生成安全URL的方法.

要获得完整的URL,我使用

echo route('my_route_name');
Run Code Online (Sandbox Code Playgroud)

但是,如果我想要一个带https的URL怎么办?

小智 62

更新:正如评论中所指出的,更简单的方法是在文件的方法中添加URL::forceSchema('https');4.2-5.3之间的Laravel URL::forceScheme('https');版本或5.4+版本.bootAppServiceProvider

老答案:

它实际上是完全可能的,只需要一行代码即可完成.

Laravel本身并不检查SSL的存在,它取决于Symfony.我们的关键是让它相信当前的要求是安全的.

问题是,我们必须设置HTTPS server param为true,最简单的方法是将以下代码粘贴到boot您的方法中AppServiceProvider:

$this->app['request']->server->set('HTTPS', true);
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我只需要在生产中强制使用SSL,本地环境应该仍然适用于http.这就是我仅在生产时强制使用SSL的方法:

$this->app['request']->server->set('HTTPS', $this->app->environment() != 'local');
Run Code Online (Sandbox Code Playgroud)

顺便说一句,请注意这些术语,将来可能需要它们.

  • 更新:Laravel 5+ - Url :: forceSchema更改为Url :: forceScheme (9认同)
  • 这实际上会欺骗整个环境,认为请求来自https,这可能是一个安全问题.我建议改为通过`URL :: forceSchema('https')`来强制https. (2认同)
  • 这有效,但对于像我这样一开始就错过它的人来说,文件顶部也需要这样:“use Illuminate\Support\Facades\URL;” (2认同)

Pri*_*rii 10

正如我在相关问题中提到的,我找到了 5 种生成安全 URL 的方法。

  1. 配置您的 Web 服务器以将所有非安全请求重定向到 https。nginx 配置示例:

    server {
        listen 80 default_server;
        listen [::]:80 default_server;
        server_name example.com www.example.com;
        return 301 https://example.com$request_uri;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. APP_URL使用 https设置环境变量:

    APP_URL=https://example.com
    
    Run Code Online (Sandbox Code Playgroud)
  3. 使用助手secure_url() (Laravel5.6)

  4. 将以下字符串添加到 AppServiceProvider::boot() 方法(适用于 5.4+ 版本):

    \Illuminate\Support\Facades\URL::forceScheme('https');
    
    Run Code Online (Sandbox Code Playgroud)
  5. 路由组隐式设置方案(Laravel5.6):

    Route::group(['scheme' => 'https'], function () {
        // Route::get(...)->name(...);
    });
    
    Run Code Online (Sandbox Code Playgroud)

    目前这种方式没有记录,但效果很好。

  • 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。- [来自评论](/review/low-quality-posts/20322282) (2认同)
  • @peterzurich 考虑到您的评论已修复 (2认同)

Mār*_*dis 9

事实证明,laravel不关心url是否安全,因为它基于当前url生成.如果您在https页面上,route()将返回安全网址.如果在http,那么http://url

问题是,Laravel没有检测到https已启用,这是由于服务器配置错误造成的.

您可以通过调用检查Laravel是否将当前连接视为https Request::isSecure();

  • 对于那些在负载均衡器或其他代理后面使用Laravel的人来说,`Request :: isSecure()`将始终返回false,除非您信任来自代理服务器的`X-Forwarded-Proto`头.请参阅:[Laravel技巧 - 在Laravel 4+中修复SSL](http://laravel-tricks.com/tricks/fix-ssl-in-laravel-4-when-server-is-behind-a-load-balancer-或-A-反向代理) (25认同)
  • @AdamLink上帝该死的,非常感谢你.我搜索了几个小时.我将在此评论中添加一些Google关键字:Laravel http https nginx反向代理,laravel route relative url https. (5认同)

Adi*_*tya 7

如果检测到传入连接是安全的,Laravel 5.x将通过route()帮助程序生成安全URL.如果应用程序隐藏在负载均衡器或代理(例如Cloudflare)后面,通常会发生问题,因为应用服务器和负载均衡器/代理之间的连接可能不安全.

我现在正在使用Laravel Forge + Cloudflare,这是我能找到的最简单的方法来启用应用程序,认为传入连接是安全的(不确定其他代理).

  1. 生成自签名证书(请参阅https://www.digitalocean.com/community/tutorials/openssl-essentials-working-with-ssl-certificates-private-keys-and-csrshttp://www.selfsignedcertificate.com/)

  2. 在Forge面板中,插入您的私钥和证书Sites > your-site > SSL Certificates > Install Existing Certificate.

  3. 启用

  4. 在CloudFlare面板中Crypto > SSL,选择"Full"(不严格)

  5. 完成(改变传播需要几分钟)

简而言之,客户端和Cloudflare之间的连接由Cloudflare自己的SSL保护.应用服务器和Cloudflare之间的连接受到您生成的证书的保护(因此应用程序看到'连接'是安全的.

您可以将相同的原则应用于其他堆栈.


小智 6

我认为只有一种方法可以做到这一点.

要生成指定路由的安全URL,您可能希望将路由传递给secure_url辅助函数.

secure_url(URL::route('your_route_name', [], false));
Run Code Online (Sandbox Code Playgroud)

您无法真正使用route辅助函数,因为它http://默认生成绝对URL(带)并且它http不是https您想要的版本


小智 6

使用secure_url:

secure_url(URL::route('your_route_name', [], false));
Run Code Online (Sandbox Code Playgroud)

您需要将 URL::route 设置为 false 才能不返回完整的 URL。然后使用 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
Run Code Online (Sandbox Code Playgroud)

https://laravel.com/api/5.4/Illuminate/Contracts/Routing/UrlGenerator.html


Osc*_*vid 6

Laravel 8

我最近通过修改这个文件解决了这个问题:

app/Providers/AppServiceProvider.php

在方法中boot()添加以下内容:

URL::forceScheme('https');
Run Code Online (Sandbox Code Playgroud)

在顶部添加使用:

use Illuminate\Support\Facades\URL;
Run Code Online (Sandbox Code Playgroud)

要在您的本地环境中工作,您可以像这样离开它:

public function boot()
{
    if(env('APP_ENV') !== 'local') {
        URL::forceScheme('https');
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:不要忘记设置你的环境变量APP_ENVprod生产文件。

APP_ENV=prod
Run Code Online (Sandbox Code Playgroud)