IT TIP

Laravel은 모든 요청을 HTTPS로 리디렉션

itqueen 2020. 12. 2. 22:23
반응형

Laravel은 모든 요청을 HTTPS로 리디렉션


전체 사이트는 https를 통해 제공됩니다. 각 경로에 'https'가 있습니다. 그러나 http를 통해 시도하는 경우 https로 리디렉션하려면 어떻게해야합니까?

Route::group(array('https'), function()
{
     // all of our routes
}

App :: before 사용

파일 App::before()블록을 활용할 수 있습니다 app/filters.php.

현재 요청이 안전한지 확인하기위한 간단한 검사를 포함하도록 블록을 변경하고 그렇지 않은 경우 리디렉션합니다.

App::before(function($request)
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }
});

필터 사용

또 다른 옵션은 이와 같은 필터를 만드는 것입니다. 사람들은 일반적으로 이것을 app/filters.php.

Route::filter('force.ssl', function()
{
    if( ! Request::secure())
    {
        return Redirect::secure(Request::path());
    }

});

그런 다음 이와 같은 경로, 경로 그룹 또는 컨트롤러에 새 필터를 적용 할 수 있습니다.

개별 노선

Route::get('something', ['before' => 'force.ssl'], function()
{
    return "This will be forced SSL";
});

루트 그룹

Route::group(['before' => 'force.ssl'], function()
{
    // Routes here.
});

제어 장치

컨트롤러의 __construct()메서드 에서이 작업을 수행해야합니다 .

public function __construct()
{
    $this->beforeFilter('force.ssl');
}

또 다른 대답은 웹 서버가 이것을 처리하도록하는 것입니다. Apache를 사용하는 경우 RedirectSSL 기능을 사용하여 모든 요청이 사이트의 HTTPS 버전으로 이동하는지 확인하고 리디렉션하지 않는 경우이를 확인할 수 있습니다. 이것은 Laravel이 요청을 받기 전에 발생합니다.

Apache RedirectSSL

NGINX를 사용하는 경우 두 개의 서버 블록을 사용하여이를 수행 할 수 있습니다. 하나는 포트 80의 일반 HTTPS 용이고 다른 하나는 포트 443의 HTTPS 용입니다. 그런 다음 항상 SSL 버전으로 리디렉션하도록 일반 서버 블록을 구성합니다.

server {
    listen 80;
    server_name mydomain.com;
    rewrite ^ https://$server_name$request_uri? permanent;
}

server {
    listen 443;
    server_name mydomain.com;
    ssl on;
    # other server config stuff here.
}

PHP 자체가 아무것도 처리 할 필요가 없기 때문에 개인적으로이 옵션을 사용합니다. 일반적으로 웹 서버 수준에서 이와 같은 검사를 처리하는 것이 더 저렴합니다.


HTTPS를 강제 Laravel 4/5 및 탄성 콩 줄기를 사용하는 사용자의 경우가 있기 때문에이 방법을 사용하여 어려운 isSecure()돌아갑니다 false. 또한 .htaccess리디렉션을 사용 하면 Chrome에 대한 리디렉션 루프가 발생하고 Firefox에서 페이지로드 시간이 지연됩니다.

이 설정은

  • Laravel 5 및 Laravel 3/4에서 작동 할 수 있습니다.
  • EC2 서버 인스턴스를 실행하는 Elastic Beanstalk에로드 된 애플리케이션
  • DNS 확인에 사용되는 Route 53
  • 모든 자산의 글로벌 CDN 및 HTTPS 적용에 사용되는 Cloudfront
  • 나는 awsWindows 시스템에서 실행 합니다. Linux는 약간 다를 수 있습니까?

몇 시간 동안 시도한 후 다음 단계를 사용하여 모든 HTTP 요청을 HTTPS로 전달했습니다.

  1. SSL 인증서를 얻습니다. 가이드와 공급자는 다양하며 Google 검색을 통해 찾을 수 있습니다.

  2. aws콘솔 명령을 사용하여 AWS에 인증서를 업로드합니다 . 명령 구조는 다음과 같습니다.

    aws iam upload-server-certificate --server-certificate-name CERTIFICATE_NAME --certificate-body "file://PATH_TO_CERTIFICATE.crt" --private-key "file://YOUR_PRIVATE_KEY.pem" --certificate-chain "file://YOUR_CERTIFICATE_CHAIN.ca-bundle" --path /cloudfront/
    
  3. Elastic Beanstalk 애플리케이션을 생성합니다. 설정 프로세스를 진행하십시오. 애플리케이션이 설정되면 구성 -> 네트워크 계층 -> 부하 분산 으로 이동하여 톱니 바퀴 아이콘을 클릭 합니다 .

  4. 보안 리스너 포트443 으로 선택하십시오 . 프로토콜HTTPS선택합니다 . SSL 인증서 ID에 대해 2 단계CERTIFICATE_NAME 에서 선택합니다 . 구성을 저장하십시오.

  5. 콘솔로 이동합니다 . EC2 인스턴스를 클릭합니다 . Load Balancers를 클릭합니다 . 부하 분산기를 클릭합니다. 인스턴스를 클릭 하고 아래로 스크롤하여 해당로드 밸런서에 할당 된 EC2 인스턴스를 확인합니다. EC2 인스턴스의 이름이 애플리케이션 URL과 같거나 가까운 경우로드 밸런서 DNS 이름기록해 둡니다. 형식이어야합니다.awseb-e-...

  6. 콘솔로 돌아갑니다 . CloudFront를 클릭 합니다. 배포 만들기를 클릭합니다 . 배포를 선택합니다 .

  7. 배포를 설정합니다. Origin Domain Name5 단계 에서 찾은로드 밸런서 DNS 이름으로 설정합니다 . HTTP를 HTTPS리디렉션 하도록 뷰어 프로토콜 정책설정합니다 . 설정 앞으로 쿼리 문자열 . 설정 대체 도메인 이름 (CNAME이) 의 URL (들)은 응용 프로그램에 사용할. 2 단계 에서 업로드 한 SSL 인증서 를로 설정 합니다 . 배포판을 만드십시오.CERTIFICATE_NAME

  8. CloudFront에서 배포 이름을 클릭합니다. 클릭 기원을 , 당신의 기원을 클릭하여 선택하고 편집을 . Origin Protocol PolicyMatch Viewer 인지 확인합니다 . 돌아 가세요. 동작을 클릭 하고 원본을 선택한 다음 편집을 클릭 합니다. Forward HeadersWhitelist로 변경 하고 Host를 추가 합니다. 저장.

  9. 콘솔로 이동합니다 . Route 53을 클릭합니다 . Hosted Zones를 클릭 합니다 . Create Hosted Zone을 클릭합니다 . 도메인 이름을 설정하십시오. 설정이 완료되면 레코드 세트 만들기를 클릭 합니다. A 레코드를 입력하십시오. AliasYes선택합니다 . 귀하의 별칭 목표는 당신의 CloudFront를 유통이다. 기록을 저장하십시오.

  10. Route 53 네임 서버를 가리 키도록 도메인의 네임 서버를 설정합니다. 모든 것이 전파 될 때까지 기다리십시오. 몇 시간이 걸릴 수 있습니다. URL로 이동하십시오. 자동으로 HTTPS로 리디렉션됩니다.

  11. "하지만 잠깐, 내 링크가 HTTPS로 이동하지 않습니다!?" X-Forwarded-ProtoCloudFront가 전달할 헤더 를 처리해야합니다 . Laravel 4의 경우이 가이드를 따르십시오 . Laravel 5의 경우 다음을 실행하십시오.

    php artisan make:middleware EB_SSL_Trust
    

그리고 이것을 EB_SSL_Trust파일에 추가 하십시오.

    public function handle($request, Closure $next)
    {
        $request->setTrustedProxies( [ $request->getClientIp() ] );
        return $next($request);
    }

그리고 이것을 App\Http\Kernel.php파일에 추가 하십시오.

    protected $middleware = [
        ...
        'App\Http\Middleware\EB_SSL_Trust',
        ...
    ];

참고 : CSS, JS 또는 이미지와 같은 모든 자산은 HTTPS를 통해 전송되어야합니다. Laravel을 사용하여 이러한 링크를 생성하는 경우을 사용 secure_asset()하여 뷰에서 HTTPS URL을 생성하십시오.


의 사용 필터 에서 사용되지 Laravel 5.1. * . 이것은 MiddleWare를위한 완벽한 작업입니다.

미들웨어를 만들고 핸들 섹션에 넣어

public function handle($request, Closure $next)
{
    if(! $request->secure()) {
        return redirect()->secure($request->path());
    }
    return $next($request);
}

그런 다음 Kernel.php에 미들웨어를 등록하고 경로 또는 컨트롤러와 함께 사용하면됩니다.


laravel 4.2.X 용 .htaccess Apache 사용

원본 파일

<IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteRule ^(.*)/$ /$1 [L,R=301]

    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

/public/.htaccess 파일 편집

 <IfModule mod_rewrite.c>
    <IfModule mod_negotiation.c>
        Options -MultiViews
    </IfModule>

    RewriteEngine On

    # Redirect Trailing Slashes...
    RewriteCond %{HTTPS} off 
    RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] 


    # Handle Front Controller...
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [L]
</IfModule>

이전 답변 결합 및 Laravel 4.2 업데이트 :

Route::filter('secure', function () {
    if (! Request::secure()) {
        return Redirect::secure(
            Request::path(),
            in_array(Request::getMethod(), ['POST', 'PUT', 'DELETE']) ? 307 : 302
        );
    }
});
Route::when('*', 'secure');

동일한 URL로 리디렉션하고 https를 사용하려면 Request::getRequestUri()대신 다음을 사용해야 합니다 Request::path().

App::before(function($request)
{
    if( ! Request::secure())
    {
         return Redirect::secure(Request::getRequestUri());
    }
});

이것은 Apache 2.4에서 나를 위해 일했습니다.

Laravel의 루트 폴더에서 .htaccess를 변경했습니다.

에서 <IfModule mod_rewrite.c> RewriteEngine On RewriteRule ^(.*)$ public/$1 [L] </IfModule>

<IfModule mod_rewrite.c> RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] RewriteRule ^(.*)$ public/$1 [L] </IfModule>


Request::secure()url이 https경우에도 어떤 이유로 false를 반환 하는 문제가있는 경우 $ _SERVER [ 'HTTPS'] 값이 존재하지 않기 때문일 수 있습니다.

이것은 해결 방법입니다.

App::before(function ($request){
    // Force https
    if(!Request::secure() && array_get($_SERVER, 'SERVER_PORT') != 443){
        return Redirect::secure(Request::path());
    }
});

POST 요청을 수행하는 동안 SSL을 강제하는 데 문제가 있습니다. 항상 GET으로 리디렉션됩니다. 이는 Redirect::secure()기본적으로 302 리디렉션을 사용 하기 때문에 발생합니다 .

POST 요청이 올바르게 리디렉션되는지 확인하려면 다음과 같이 사용하십시오.

return Redirect::secure("your/path/here", 307)

이렇게하면 리디렉션이 발생한 후에도 요청이 원래 요청 방법을 유지할 수 있습니다.


I don't understand about HTTP and HTTPS in detail, so I'm sorry if this answer isn't very good.

It's my understanding that there is an issue that even when client and (client specified) server are using HTTPS, Request::secure() can return false because your application may be running on a different server, which is possibly not receiving a https request.

I'm hosting my laravel app in heroku and it seems it does that. My guess is that the primary (client specified) server is a load balancer and when the request is forwarded, it arrives at the other server as a normal HTTP request.

When such forwarding can happen, you should not just check for Request::secure() to be true. I was instructed (by someone in #laravel @ irc.freenode.com) to also check Request::server('HTTP_X_FORWARDED_PROTO') to see if it's equal to 'https'.

So if you intend to follow the other advice in here and perform a redirect in case of non-secure, try checking for this server parameter too.


For laravel 5.1 you should use given code in App\Http\Providers\RouteServiceProvider@boot

$router->filter('force.ssl', function () {
      if ( ! request()->secure() ) {
           return redirect()->secure(request()->path());
      }
});

Now you can use this in routes file.

Route::group(['before' => 'force.ssl'], function () {
    // Routes here
});

you can also add ['before' => 'force.ssl'] in $router->group() in

App\Http\Providers\RouteServiceProvider@map

If behind a proxy and Request::secure() is not working.

App::before( function( $request )
{
  // set the current IP (REMOTE_ADDR) as a trusted proxy
  Request::setTrustedProxies( [ $request->getClientIp() ] );
});

Combining previous answers to use constants and methods that are available in Laravel 4.2.

routes.php

Route::when('*', 'secure');

filters.php

use Illuminate\Http\Response as IlluminateResponse;

Route::filter('secure', function ()
{
    if ( ! Request::secure() && Request::getPort() != 443)
    {
        return Redirect::secure(
            Request::path(),
            in_array(Request::getMethod(), ['POST', 'PUT', 'DELETE'])
                ? IlluminateResponse::HTTP_TEMPORARY_REDIRECT
                : IlluminateResponse::HTTP_FOUND
        );
    }
});

If you have to use Laravel 4 itself to handle the redirecting (like me), I'd go for the following setup (explanation as comments in the code):

Route filter:

// app/filters.php
Route::filter('ssl.force', function()
{
    if(App::environment('production') && !Request::secure())
    {
        // don't set a session cookie when redirecting to another scheme to 
        // avoid dropping the session when switching scheme
        Config::set('session.driver', 'array');
        // preserve query string while redirecting by using fullUrl()
        // instead of Redirect::secure + Request::path()
        $url = str_replace('http://', 'https://', Request::fullUrl());
        return Redirect::to($url, 302, array(), true);
    }

    // secure cookies for https
    Config::set('session.secure', Request::secure());
});

Then apply the filter as a before filter to your route or route group. eg:

// app/routes.php
Route::group(array('before' => 'ssl.force'), function () {
    // SSL routes
});

참고URL : https://stackoverflow.com/questions/19967788/laravel-redirect-all-requests-to-https

반응형