Nig*_*ICU 107 php laravel laravel-routing laravel-5
在我的第一个Laravel 5项目上工作,不确定在我的应用程序中强制使用HTTPS的逻辑位置和方式.这里的关键是有许多域指向应用程序,只有三分之二使用SSL(第三个是后备域,长篇故事).所以我想在我的应用程序逻辑而不是.htaccess中处理这个问题.
在Laravel 4.2中,我使用此代码完成了重定向,位于filters.php:
App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
Run Code Online (Sandbox Code Playgroud)
我认为中间件应该在这样的地方实现,但我不能完全理解这一点.
谢谢!
UPDATE
如果您像我一样使用Cloudflare,可以通过在控制面板中添加新的页面规则来实现.
man*_*nix 226
您可以使它适用于中间件类.让我给你一个想法.
namespace MyApp\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\App;
class HttpsProtocol {
public function handle($request, Closure $next)
{
if (!$request->secure() && App::environment() === 'production') {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,将此中间件应用于每个请求添加在Kernel.php文件中设置规则,如下所示:
protected $middleware = [
'Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode',
'Illuminate\Cookie\Middleware\EncryptCookies',
'Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse',
'Illuminate\Session\Middleware\StartSession',
'Illuminate\View\Middleware\ShareErrorsFromSession',
// appending custom middleware
'MyApp\Http\Middleware\HttpsProtocol'
];
Run Code Online (Sandbox Code Playgroud)
在上面的示例中,如果出现以下情况,中间件会将每个请求重定向到https:
production.因此,只需根据您的喜好调整设置即可.我在生产环境中使用带有WildCard SSL的代码,代码正常工作.如果我&& App::environment() === 'production'在localhost中删除并测试它,重定向也可以.因此,安装或不安装SSL不是问题.看起来你需要非常注意你的Cloudflare层才能被重定向到Https协议.
感谢您@Adam Link的建议:它可能是由Cloudflare传递的标头引起的.CloudFlare可能通过HTTP命中您的服务器并传递X-Forwarded-Proto标头,声明它正在转发HTTPS请求.您需要在中间件中添加另一行说...
$request->setTrustedProxies( [ $request->getClientIp() ] );
Run Code Online (Sandbox Code Playgroud)
...信任CloudFlare正在发送的标头.这将停止重定向循环
只需要将中间件类添加到web组中kernel.php file:
protected $middlewareGroups = [
'web' => [
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// here
\MyApp\Http\Middleware\HttpsProtocol::class
],
];
Run Code Online (Sandbox Code Playgroud)
请记住,
web默认情况下,组应用于每个路由,因此您无需web在路由或控制器中明确设置.
App::environment() === 'production'.对于以前的版本是
env('APP_ENV') === 'production'.\URL::forceScheme('https');实际上不重定向.它只是在https://呈现网站时构建链接.小智 53
另一个适合我的选项,在AppServiceProvider中将此代码放在boot方法中:
\URL::forceScheme('https');
Run Code Online (Sandbox Code Playgroud)
在forceSchema('https')之前编写的函数是错误的,它的forceScheme
Ass*_* Ch 29
或者,如果您使用的是Apache,则可以使用.htaccessfile强制您的URL使用https前缀.在Laravel 5.4上,我在我的.htaccess文件中添加了以下行,它对我有用.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
Run Code Online (Sandbox Code Playgroud)
小智 16
对于laravel 5.4使用此格式来获取https重定向而不是.htaccess
namespace App\Providers;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
URL::forceScheme('https');
}
}
Run Code Online (Sandbox Code Playgroud)
Mla*_*vic 10
类似于manix的答案,但在一个地方.中间件强制HTTPS
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
class ForceHttps
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if (!app()->environment('local')) {
// for Proxies
Request::setTrustedProxies([$request->getClientIp()]);
if (!$request->isSecure()) {
return redirect()->secure($request->getRequestUri());
}
}
return $next($request);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 7
这适用于Larave 5.2.x及更高版本.如果您想要通过HTTPS提供一些内容以及通过HTTP提供其他内容,这里有一个适合我的解决方案.您可能想知道,为什么有人想通过HTTPS只提供一些内容?为什么不通过HTTPS提供服务?
虽然通过HTTPS服务整个站点完全没问题,但通过HTTPS切断所有内容会对服务器产生额外的开销.记住加密并不便宜.轻微的开销也会对您的应用响应时间产生影响.你可以说商品硬件价格便宜且影响可以忽略不计但是我离题:)我不喜欢用https来提供图片等营销内容大页面的想法.所以这就是它.它与上面使用中间件的建议类似,但它是一个完整的解决方案,允许您在HTTP/HTTPS之间来回切换.
首先创建一个中间件.
php artisan make:middleware ForceSSL
Run Code Online (Sandbox Code Playgroud)
这就是您的中间件应该是什么样子.
<?php
namespace App\Http\Middleware;
use Closure;
class ForceSSL
{
public function handle($request, Closure $next)
{
if (!$request->secure()) {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
Run Code Online (Sandbox Code Playgroud)
请注意,我不是基于环境进行过滤,因为我为本地开发和生产都设置了HTTPS,因此不需要.
以下内容添加到您的routeMiddleware \软件\ HTTP\Kernel.php让你可以挑选哪些航线组应强制SSL.
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'can' => \Illuminate\Foundation\Http\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'forceSSL' => \App\Http\Middleware\ForceSSL::class,
];
Run Code Online (Sandbox Code Playgroud)
接下来,我想确保两个基本组登录/注册等以及Auth中间件后面的所有其他内容.
Route::group(array('middleware' => 'forceSSL'), function() {
/*user auth*/
Route::get('login', 'AuthController@showLogin');
Route::post('login', 'AuthController@doLogin');
// Password reset routes...
Route::get('password/reset/{token}', 'Auth\PasswordController@getReset');
Route::post('password/reset', 'Auth\PasswordController@postReset');
//other routes like signup etc
});
Route::group(['middleware' => ['auth','forceSSL']], function()
{
Route::get('dashboard', function(){
return view('app.dashboard');
});
Route::get('logout', 'AuthController@doLogout');
//other routes for your application
});
Run Code Online (Sandbox Code Playgroud)
确认您的中间件已从控制台正确应用于您的路由.
php artisan route:list
Run Code Online (Sandbox Code Playgroud)
现在你已经获得所有的表格或应用程序的敏感区域,现在的关键是使用你的视图模板来定义您的安全和公众(非HTTPS)的链接.
根据上面的示例,您将如下呈现您的安全链接 -
<a href="{{secure_url('/login')}}">Login</a>
<a href="{{secure_url('/signup')}}">SignUp</a>
Run Code Online (Sandbox Code Playgroud)
非安全链接可以呈现为
<a href="{{url('/aboutus',[],false)}}">About US</a></li>
<a href="{{url('/promotion',[],false)}}">Get the deal now!</a></li>
Run Code Online (Sandbox Code Playgroud)
这样做会呈现一个完全限定的URL,例如https:// yourhost/login 和http:// yourhost/aboutus
如果你不渲染以http完全合格的URL,并使用相对链接URL("/关于我们"),则用户访问安全站点后,HTTPS将仍然存在.
希望这可以帮助!
仅使用.htaccess文件来实现https重定向怎么办?应将其放置在项目根目录中(而不是公共文件夹中)。您的服务器需要配置为指向项目根目录。
<IfModule mod_rewrite.c>
RewriteEngine On
# Force SSL
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
# Remove public folder form URL
RewriteRule ^(.*)$ public/$1 [L]
</IfModule>
Run Code Online (Sandbox Code Playgroud)
我将其用于laravel 5.4(编写此答案时的最新版本),但即使laravel更改或删除了某些功能,它也应继续适用于功能版本。
在 Laravel 5.1 中,我使用: 文件:app\Providers\AppServiceProvider.php
public function boot()
{
if ($this->isSecure()) {
\URL::forceSchema('https');
}
}
public function isSecure()
{
$isSecure = false;
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') {
$isSecure = true;
} elseif (!empty($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https' || !empty($_SERVER['HTTP_X_FORWARDED_SSL']) && $_SERVER['HTTP_X_FORWARDED_SSL'] == 'on') {
$isSecure = true;
}
return $isSecure;
}
Run Code Online (Sandbox Code Playgroud)
注意:使用forceSchema, NOTforceScheme
| 归档时间: |
|
| 查看次数: |
152361 次 |
| 最近记录: |