Laravel 5 - 发布路由上的 htaccess HTTPS 重定向不起作用。

Posted

技术标签:

【中文标题】Laravel 5 - 发布路由上的 htaccess HTTPS 重定向不起作用。【英文标题】:Laravel 5 - htaccess HTTPS redirect on post routes doesn't work. 【发布时间】:2016-05-25 18:12:30 【问题描述】:

我有一个使用 Laravel 5 作为 API 构建的应用程序。我的 .htaccess 文件中有以下内容可将所有路由重定向到 https:

  RewriteEngine On

    # Force SSL
    RewriteCond %HTTPS !=on
    RewriteRule ^ https://%HTTP_HOST%REQUEST_URI [L,R=301]

这适用于以下情况:

https://example.com/route

但如果我尝试使用 http 访问它,则会引发 MethodNotAllowedHttpException。它正确重定向到 https,但似乎没有正确跟随 POST 请求,因为我的所有路由都只允许 POST。

有没有什么办法可以在不改变我的路由以允许 GET 的情况下解决这个问题?

【问题讨论】:

【参考方案1】:

为了强制使用 https,您的 RewriteRule 需要强制进行外部重定向。对于您的规则,您强制执行 301 重定向 (R=301)。大多数浏览器和客户端都设计为自动跟踪重定向,但它们(错误地)通过 GET 请求这样做。

因此,当客户端向http://example.com/route 发送带有数据的 POST 请求时,您的服务器会以 301 重定向响应 https://example.com/route,然后客户端会向新 URL 发出不带数据的 GET 请求。如您所见,您不能只更改路由以接受 GET 请求,因为原始 POST 请求中发送的数据将被丢弃。

一种选择是添加一个重写条件以不重定向 POST 请求:

# Force SSL
RewriteCond %HTTPS !=on
RewriteCond %REQUEST_METHOD !=POST
RewriteRule ^ https://%HTTP_HOST%REQUEST_URI [L,R=301]

但是,这几乎违背了您尝试完成的目的。这整个概念是在任何地方强制使用 https。除非将数据发布到您的应用程序,否则在任何地方都强制执行它是愚蠢的。

另一个可能的选择是将您的 301 重定向更改为 307 重定向。尽管客户端不应该更改 301/302 重定向的请求方法,但由于规范和现有功能的模糊性,大多数客户端都会这样做。因此,添加了 307 的具体想法是,如果使用此状态码,则不得更改请求方法。但是,307 被归类为“临时重定向”,因此不会被缓存,可能会影响您的 SEO。此外,此状态是在 HTTP/1.1 规范中添加的,因此您可能会遇到一些不知道如何处理 307 的客户端。

您最好的选择可能只是拒绝不安全的 POST 请求。或者,将它们重定向到一个错误页面,说明您不接受不安全的 POST 请求。

RewriteEngine On

# Forbid non-secure POSTs
RewriteCond %HTTPS !=on
RewriteCond %REQUEST_METHOD =POST
RewriteRule ^ / [F,L]

# Force SSL
RewriteCond %HTTPS !=on
RewriteRule ^ https://%HTTP_HOST%REQUEST_URI [L,R=301]

【讨论】:

你是说真的没有办法通过htaccess成功将http重定向到https的post请求吗? @mykoman 正如答案中提到的,您可以使用 307 重定向而不是 301/302,但有一些注意事项您可能关心也可能不关心。【参考方案2】:

在apache.conf中添加如下配置

<Directory /var/www/>
    Options Indexes FollowSymLinks MultiViews
        AllowOverride All
        Order allow,deny
        allow from all
        Require all granted
</Directory>

【讨论】:

以上是关于Laravel 5 - 发布路由上的 htaccess HTTPS 重定向不起作用。的主要内容,如果未能解决你的问题,请参考以下文章

从 URL Laravel 5.3 中删除公共

Laravel 5.6 上的 Ajax 身份验证重定向

Laravel public/subfolder 另一个源码

如何在 laravel 5.4 中实现 HTTPS

此路由不支持 GET 方法。支持的方法:POST。 laravel 5.8 阿贾克斯

laravel如何路由到javascript上的路由?