我有一个使用Laravel 5构建的应用程序作为API。我在.htaccess文件中有以下内容将所有路由重定向到https:
RewriteEngine On
# Force SSL
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
这适用于以下情况:
但如果我尝试使用http访问它,则会抛出MethodNotAllowedHttpException。它正确地重定向到https,但似乎没有正确地跟随POST请求,因为我的所有路由只允许POST。
有没有办法解决这个问题而不改变我的路线以允许GET?
答案 0 :(得分:4)
为了强制使用https,您的RewriteRule需要强制进行外部重定向。如果是您的规则,则会强制执行301重定向(R=301
)。大多数浏览器和客户端都设计为自动遵循重定向,但它们(错误地)通过GET请求执行此操作。
因此,当客户端向http://example.com/route
发送包含数据的POST请求时,您的服务器会以301重定向到https://example.com/route
进行响应,然后客户端发出GET请求而不将数据发送到新URL 。如您所见,您也不能仅仅更改您的路由以接受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]