Laravel 5-HTTPS로 리디렉션
내 첫 번째 Laravel 5 프로젝트에서 작업하고 있으며 내 앱에서 HTTPS를 강제하는 로직을 어디에 어떻게 배치해야하는지 모르겠습니다. 여기서 중요한 점은 앱을 가리키는 도메인이 많고 세 개 중 두 개만 SSL을 사용한다는 것입니다 (세 번째는 폴백 도메인, 긴 이야기). 그래서 .htaccess가 아닌 내 앱의 논리에서 이것을 처리하고 싶습니다.
Laravel 4.2에서는 다음 위치에있는이 코드로 리디렉션을 수행했습니다 filters.php
.
App::before(function($request)
{
if( ! Request::secure())
{
return Redirect::secure(Request::path());
}
});
나는 미들웨어가 이와 같은 것을 구현해야한다고 생각하지만 그것을 사용하여 이것을 알 수는 없습니다.
감사!
최신 정보
저처럼 Cloudflare를 사용하는 경우 제어판에 새 페이지 규칙을 추가하면됩니다.
미들웨어 클래스로 작동하도록 만들 수 있습니다. 내가 당신에게 아이디어를 드리겠습니다.
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);
}
}
그런 다음이 미들웨어를 다음 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'
];
위의 샘플에서 미들웨어는 다음과 같은 경우 모든 요청을 https로 리디렉션합니다.
- 현재 요청에는 보안 프로토콜 (http)이 없습니다.
- 환경이
production
. 따라서 기본 설정에 따라 설정을 조정하십시오.
Cloudflare
이 코드를 WildCard SSL이있는 프로덕션 환경에서 사용하고 있으며 코드가 올바르게 작동합니다. && App::environment() === 'production'
localhost에서 제거 하고 테스트하면 리디렉션도 작동합니다. 따라서 SSL이 설치되어 있는지 여부는 문제가되지 않습니다. Https 프로토콜로 리디렉션 되려면 Cloudflare 계층에 매우 세심한주의를 기울여야 할 것 같습니다.
23/03/2015 수정
@Adam Link
의 제안 덕분에 Cloudflare가 전달하는 헤더 때문일 수 있습니다. CloudFlare는 HTTP를 통해 서버에 도달하고 HTTPS 요청을 전달 중임을 선언하는 X-Forwarded-Proto 헤더를 전달합니다. 미들웨어에 다음과 같은 다른 줄을 추가해야합니다.
$request->setTrustedProxies( [ $request->getClientIp() ] );
... CloudFlare가 보내는 헤더를 신뢰합니다. 이렇게하면 리디렉션 루프가 중지됩니다.
2016 년 9 월 27 일 수정-Laravel v5.3
미들웨어 클래스를 다음 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
],
];
그 기억
web
설정할 필요가 없습니다 그룹은 기본적으로 모든 경로에 적용되는web
경로 나 컨트롤러에 명시 적으로.
2018/08/23 편집-Laravel v5.7
- 환경에 따라 요청을 리디렉션하려면
App::environment() === 'production'
. 이전 버전의 경우env('APP_ENV') === 'production'
. \URL::forceScheme('https');
실제로 사용하면 리디렉션되지 않습니다.https://
웹 사이트가 렌더링되면 링크를 만듭니다 .
나를 위해 일한 다른 옵션은 AppServiceProvider에서 다음 코드를 부팅 방법에 배치합니다.
\URL::forceScheme('https');
forceScheme ( 'https') 이전에 작성된 함수가 잘못되었습니다. forceScheme
또는 Apache를 사용하는 경우 .htaccess
파일을 사용하여 URL이 https
접두사 를 사용하도록 할 수 있습니다 . Laravel 5.4에서 .htaccess
파일에 다음 줄을 추가 했으며 저에게 효과적 이었습니다.
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule ^.*$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
laravel 5.4의 경우이 형식을 사용하여 .htaccess 대신 https 리디렉션을 가져옵니다.
namespace App\Providers;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
URL::forceScheme('https');
}
}
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);
}
}
이것은 Larave 5.2.x 이상을위한 것입니다. HTTPS를 통해 일부 콘텐츠를 제공하고 HTTP를 통해 다른 콘텐츠를 제공하는 옵션을 원한다면 여기에 저에게 효과적인 솔루션이 있습니다. 누군가 HTTPS를 통해 일부 콘텐츠 만 제공하려는 이유가 궁금 할 수 있습니다. HTTPS를 통해 모든 것을 제공하지 않는 이유는 무엇입니까?
하지만 HTTPS를 통해 전체 사이트를 제공하는 것은 괜찮지 만 HTTPS를 통해 모든 것을 분리하면 서버에 추가 오버 헤드가 발생합니다. 암호화는 저렴하지 않습니다. 약간의 오버 헤드도 앱 응답 시간에 영향을줍니다. 상용 하드웨어가 저렴하고 그 영향은 무시할 만하다고 주장 할 수 있습니다.하지만 저는 무시합니다. :) https를 통해 이미지 등이 포함 된 마케팅 콘텐츠 큰 페이지를 제공하는 아이디어가 마음에 들지 않습니다. 그래서 여기에 있습니다. 다른 사람들이 미들웨어를 사용하여 위에서 제안한 것과 유사하지만 HTTP / HTTPS간에 전환 할 수있는 완전한 솔루션입니다.
먼저 미들웨어를 만듭니다.
php artisan make:middleware ForceSSL
이것이 미들웨어의 모습입니다.
<?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);
}
}
로컬 개발 및 프로덕션 모두에 대해 HTTPS 설정이 있으므로 환경을 기반으로 필터링하지 않으므로 필요하지 않습니다.
routeMiddleware \ App \ 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,
];
다음으로, 두 개의 기본 그룹 로그인 / 가입 등과 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
});
미들웨어가 콘솔에서 경로에 올바르게 적용되었는지 확인하십시오.
php artisan route:list
이제 애플리케이션의 모든 양식 또는 민감한 영역을 보호했습니다. 이제 핵심은보기 템플릿을 사용하여 보안 및 공개 (비 https) 링크를 정의하는 것입니다.
위의 예를 기반으로 다음과 같이 보안 링크를 렌더링합니다.
<a href="{{secure_url('/login')}}">Login</a>
<a href="{{secure_url('/signup')}}">SignUp</a>
비보안 링크는 다음과 같이 렌더링 될 수 있습니다.
<a href="{{url('/aboutus',[],false)}}">About US</a></li>
<a href="{{url('/promotion',[],false)}}">Get the deal now!</a></li>
이것이하는 일은 https : // yourhost / login 및 http : // yourhost / aboutus 와 같은 정규화 된 URL을 렌더링하는 것입니다 .
http로 정규화 된 URL을 렌더링하지 않고 상대 링크 url ( '/ aboutus')을 사용하는 경우 사용자가 보안 사이트를 방문한 후에도 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>
나는 이것을 laravel 5.4 (이 답변을 쓰는 현재 최신 버전)에 사용하지만 laravel이 일부 기능을 변경하거나 제거하더라도 기능 버전에서 계속 작동합니다.
RewriteRule을 사용하여 index.php와 동일한 폴더에 .htaccess ssl을 강제 할 수 있습니다.
그림 첨부로 추가하고 다른 모든 규칙 앞에 추가하십시오.
IndexController.php에 넣어
public function getIndex(Request $request)
{
if ($request->server('HTTP_X_FORWARDED_PROTO') == 'http') {
return redirect('/');
}
return view('index');
}
AppServiceProvider.php에서
public function boot()
{
\URL::forceSchema('https');
}
AppServiceProvider.php에서 모든 리디렉션은 url https로 이동하고 http 요청의 경우 한 번 리디렉션이 필요하므로 IndexController.php에서 한 번만 리디렉션하면됩니다.
위의 답변은 저에게 효과가 없었지만 Deniz Turan은 여기에서 Heroku의로드 밸런서와 함께 작동하는 방식으로 .htaccess를 다시 작성한 것으로 보입니다 : https://www.jcore.com/2017/01/29/force-https -heroku-using-htaccess /
RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
CloudFlare를 사용하는 경우 항상 HTTPS를 사용하도록 페이지 규칙을 만들 수 있습니다. 이렇게하면 모든 http : // 요청이 https : //로 리디렉션됩니다.
그 외에도 \ app \ Providers \ AppServiceProvider.php boot () 함수에 다음과 같은 내용을 추가해야합니다.
if (env('APP_ENV') === 'production' || env('APP_ENV') === 'dev') {
\URL::forceScheme('https');
}
이렇게하면 앱의 모든 링크 / 경로가 http : // 대신 https : //를 사용하게됩니다.
Heroku에서 수행하는 방법은 다음과 같습니다.
로컬이 아닌 dyno에 SSL을 강제하려면 public /의 .htaccess 끝에 추가하십시오.
# Force https on heroku...
# Important fact: X-forwarded-Proto will exist at your heroku dyno but wont locally.
# Hence we want: "if x-forwarded exists && if its not https, then rewrite it":
RewriteCond %{HTTP:X-Forwarded-Proto} .
RewriteCond %{HTTP:X-Forwarded-Proto} !https
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
다음을 사용하여 로컬 컴퓨터에서이를 테스트 할 수 있습니다.
curl -H"X-Forwarded-Proto: http" http://your-local-sitename-here
그러면 헤더가 heroku에 걸릴 형식으로 X- 포워딩됩니다.
즉, heroku dyno가 요청을 보는 방법을 시뮬레이션합니다.
로컬 컴퓨터에서이 응답을 받게됩니다.
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://tm3.localhost:8080/">here</a>.</p>
</body></html>
그것은 리디렉션입니다. 위와 같이 .htaccess를 설정하면 heroku가 클라이언트에게 돌려 줄 것입니다. 그러나 X-forwarded가 설정되지 않기 때문에 로컬 컴퓨터에서는 발생하지 않습니다 (위의 컬을 사용하여 어떤 일이 발생하는지 확인하기 위해 위조).
Laravel 5.6의 경우 작동하도록 조건을 약간 변경해야했습니다.
에서:
if (!$request->secure() && env('APP_ENV') === 'prod') {
return redirect()->secure($request->getRequestUri());
}
에:
if (empty($_SERVER['HTTPS']) && env('APP_ENV') === 'prod') {
return redirect()->secure($request->getRequestUri());
}
이것은 나를 위해 일했습니다. https로 리디렉션하도록 사용자 지정 PHP 코드를 만들었습니다. header.php에이 코드를 포함하기 만하면됩니다.
<?php
if (isset($_SERVER['HTTPS']) &&
($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) ||
isset($_SERVER['HTTP_X_FORWARDED_PROTO']) &&
$_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') {
$protocol = 'https://';
}
else {
$protocol = 'http://';
}
$notssl = 'http://';
if($protocol==$notssl){
$url = "https://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";?>
<script>
window.location.href ='<?php echo $url?>';
</script>
<?php } ?>
이 문제로 많은 고통을 겪었 으므로이 대안을 추가하고 있습니다. 나는 모든 다른 방법을 시도했지만 아무것도 효과가 없었습니다. 그래서 해결 방법을 찾았습니다. 최선의 해결책이 아닐 수도 있지만 작동합니다.
참고로, 저는 Laravel 5.6을 사용하고 있습니다.
if (App::environment('production')) {
URL::forceScheme('https');
}
생산 <-.env 파일의 APP_ENV 값으로 바꿔야합니다.
Laravel 5.6.28 다음 미들웨어에서 사용하고 있습니다.
namespace App\Http\Middleware;
use App\Models\Unit;
use Closure;
use Illuminate\Http\Request;
class HttpsProtocol
{
public function handle($request, Closure $next)
{
$request->setTrustedProxies([$request->getClientIp()], Request::HEADER_X_FORWARDED_ALL);
if (!$request->secure() && env('APP_ENV') === 'prod') {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
가장 쉬운 방법은 응용 프로그램 수준입니다. 파일에서
app/Providers/AppServiceProvider.php
다음을 추가하십시오.
use Illuminate\Support\Facades\URL;
그리고 boot () 메서드에서 다음을 추가합니다.
$this->app['request']->server->set('HTTPS', true);
URL::forceScheme('https');
이렇게하면 응용 프로그램 수준에서 모든 요청이 https로 리디렉션됩니다.
(참고 : 이것은 laravel 5.5 LTS로 테스트되었습니다)
Laravel 5.7에서 테스트 된 약간 다른 접근 방식
<?php
namespace App\Http\Middleware;
use Closure;
class ForceHttps
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$app_url = env('APP_URL');
if ( !$request->secure() && substr($app_url, 0, 8) === 'https://' ) {
return redirect()->secure($request->getRequestUri());
}
return $next($request);
}
}
참고 URL : https://stackoverflow.com/questions/28402726/laravel-5-redirect-to-https
'Programming' 카테고리의 다른 글
설치 후 카르마를 실행하면 '카르마'가 내부 또는 외부 명령으로 인식되지 않습니다. (0) | 2020.08.10 |
---|---|
효과가 끝날 때까지 jQuery를 기다리는 방법은 무엇입니까? (0) | 2020.08.10 |
NuGet 자동 패키지 복원이 MSBuild에서 작동하지 않음 (0) | 2020.08.10 |
제약 조건이 높이 0을 모호하게 제안하는 경우 감지 (0) | 2020.08.10 |
Netbeans 성능을 향상시키는 방법은 무엇입니까? (0) | 2020.08.09 |