2014-03-24 4 views
18

공개 사이트에서 Laravel의 CSRF 보호를 사용하고 있습니다. 그러나 Laravel이 이것을 유지하기 위해 세션을 사용하기 때문에 사용자가 컴퓨터에서 멀어지고 이전에 열어 둔 페이지로 돌아가는 경우에만 AJAX 요청이 작동하지 않는다는 것을 발견 할 수 있습니다. 세션 시간이 초과되어 토큰이 더 이상 유효하지 않으므로 Ajax 요청이 작동하지 않습니다. 이러한 사용자가 "로그인 한"사용자 인 경우 로그인 페이지로 다시 리디렉션 할 수 있습니다. 사용자는 공개 사용자이므로 페이지를 새로 고쳐야 강제로 다시 작동합니다 (어색한).Laravel은 CSRF 토큰을 얼마나 구체적으로 빌드하고 검사합니까?

아니면 내가 잘못 했습니까? CSRF 토큰이 Laravel에 의해 여전히 유효성을 확인합니까? (세션이 만료 된 후에도 페이지가 토큰을 계속 전송하지만 ... Laravel이이를 어떻게 처리합니까?). 최적의 솔루션은 세션 시간 제한과 별도로 토큰 만료 제한을 부여 할 수 있도록 타임 스탬프에 부분적으로 토큰을 사용하는 것입니다. 내 CSRF 토큰을 2 일 동안 지속시킬 수 있습니다. 따라서 2 일 동안 멀리 걸어가는 사용자 만이 죽은 페이지로 돌아갑니다.

궁극적으로이 질문을 내게 : 이 처리하는 Laravel 프레임 워크의 특정 코드는 무엇입니까? 현재 찾으려고합니다. 또한, 내가 할 수있는 교체에 쉽게 드롭 또는 내 페이지로 출력 csrf_token(); 내 자신의 버전을 만들려면 남겨두고 난 그걸로 갈 자신의 경로 필터를 만들 필요가있다.

답변

23

Laravel은 토큰을 세션에 저장하여 쉽게 사용할 수 있지만 코드는 실제로 사용자가 원하는대로 변경할 수 있습니다. 그것은 당신이 경로가있는 경우라고 우리에게 이야기한다

Route::filter('csrf', function() 
{ 
    if (Session::token() != Input::get('_token')) 
    { 
     throw new Illuminate\Session\TokenMismatchException; 
    } 
}); 

: 당신은 filters.php에서 봐를 볼 사용자 세션이 만료

Route::post('myform', ['before' => 'csrf', 'uses' => '[email protected]']); 

그리고를, 예외를 제기합니다,하지만 당신은 할 수 있습니다 자신을 일을 자신의 토큰이 더 나은 생각 어디에 저장하고, 대신에 예외를 던지는, 로그인 페이지로 사용자를 리디렉션 유지 : 예, 당신은 creat에 수

Route::filter('csrf', function() 
{ 
    if (MySession::token() != MyCSRFToken::get()) 
    { 
     return Redirect::to('login'); 
    } 
}); 

그리고 e 고객님의 csrf_token(), Laravel이하기 전에로드해야합니다. 내가하기로 결정,이 이후

if (! function_exists('csrf_token')) 
{ 
    function csrf_token() 
    { 
     ... 
    } 
} 
+1

아에... 나는이 코드를 알고 있었다, 그러나 나는 실제로 수행되고 있는지 계산 보려고 프레임 워크에 깊은 찾고 있었다. 그러나 CSRF를 위해 여기에서 세션이 사용되고 있음을 분명히 볼 수 있습니다. CSRF 보호의 일반적인 사용법은 로그인 한 사용자를위한 것이라고 생각합니다.그러나 나는 JSON을 내 사이트의 다른 공개 영역에서 보내고 있는데, 일부 공용 API처럼 사이트를 사용해 볼 수있는 사람들이 쉽게 잡아 먹고 싶지 않습니다. – prograhammer

+0

그리고 ... 저 헬퍼를 무시할 수 있다고 상기시켜줌으로써 당신을 정말로 도왔습니다. 그래서 안전한 내기는 저를 다시 쓰고 세션에서이 토큰을 얻는 것입니다. Antonio에게 다시 한 번 감사드립니다! – prograhammer

4

인기 질문이되었다 : 당신이 Laravel 소스 코드에서 helpers.php 파일을 보면,`게요은 이미 존재하지 않는 경우에만 해당 기능을 만들어 볼 매우 정교하게 작업 해 온 나의 구체적인 솔루션을 게시하십시오 ...

대부분의 경우 귀하의 모든 페이지 상단에 header.php 또는 일부 부분보기를 사용하게 될 것이므로 <head> 섹션 :

<meta name="_token" content="<?=csrf_token(); ?>" /> 

filters.php : 0

Route::filter('csrf', function() 
{ 
    if (Request::ajax()) { 
     if(Session::token() != Request::header('X-CSRF-Token')){ 
      throw new Illuminate\Session\TokenMismatchException; 
     } 
    } 
}); 

그리고 당신의 routes.php

Route::group(array('before' => 'csrf'), function(){ 

    // All routes go in here, public and private 

}); 
+2

ajax 호출을 사용하는 경우 약간의 정보를 추가하기 만하면 다음 jQuery.ajaxSetup ({headers : { 'X-CSRF-Token': $ ('meta [name = _token]')을 사용할 수 있습니다. 'content')}});'[source] (http://laravel.io/forum/04-03-2014-simple-ajax-post-response-in-laravel-4#reply-11226) –

+0

그래. 이것이 내가 Laravel 5에서하는 것입니다. 실제로 Laravel 문서에서 언급되었습니다. :-) – prograhammer

관련 문제