2016-02-12 72 views
3

會話過期時,由於ajax標頭中的_token已過期(AKA TokenMismatchException),用戶無法重新登錄而無法刷新頁面。我不能通過將用戶重定向到登錄頁面來處理異常,因爲登錄是疊加模式,並且通過ajax處理請求。如何在會話過期時處理laravel TokenMismatchException

我想我可以趕上Handler.php中的不匹配異常並返回帶有會話令牌的json響應。並在客戶端,使用新的令牌來繼續預期的過程。但是,當我使用從服務器傳遞的新令牌時,會話令牌將在服務器端再次更改,導致另一個TokenMismatchException

那麼我應該如何處理異常以安全的方式,而不刷新頁面?

這就是我現在所擁有的:

設置csrf_token在全球js文件:

$(function() { 
     $.ajaxSetup({ 
     headers: { 'X-CSRF-TOKEN': $('meta[name="csrf_token"]').attr('content') } 
     }); 
    }); 

呈現在app /異常/ handler.php方法:在認證

public function render($request, Exception $e) 
    { 
     if ($this->isHttpException($e)) 
     { 
      return $this->renderHttpException($e); 
     } 
     else if ($e instanceof TokenMismatchException) 
     { 
      if ($request->ajax()) { 
       return response()->json([ 
        'message' => 'TokenMismatchException', 
        'token' => csrf_token() 
       ]); 
      } 
     } 
     else 
     { 
      return parent::render($request, $e); 
     } 
    } 

.js:

$.ajax({ 
    type: "POST", 
    url: "/auth/login", 
    data: { 
     "email" : $('#login_email').val(), 
     "password" : $('#login_password').val(), 
     'remember': $('#login_remember').is(':checked') 
    }, 
    success: function(response) { 
     if (response.message === 'TokenMismatchException') { 
     console.log(response); //message and token exist 
     //if catch the exception, use the new token to set up the ajax headers and login again 

      $.ajaxSettings.headers["X-CSRF-TOKEN"] = response.token; 
      console.log($.ajaxSettings.headers["X-CSRF-TOKEN"]); 
      $.ajax({ 
      type: "POST", 
      url: "/auth/login", 
      data: { 
       "email" : $('#login_email').val(), 
       "password" : $('#login_password').val(), 
       'remember': $('#login_remember').is(':checked'), 
      }, 
      success: function(res) { 
       console.log(res); 

      }, 
      error: function(err) { 
       console.log(err); 
      } 
     }); 

     } 
     console.log('logged in'); 
    }, 
    error: function(xhr, status, err) { 
    } 
    }); 

在此先感謝。

回答

1

在渲染函數中,您必須檢查特定的TokenMismatchException。所以,可能是你可以嘗試這樣的:

if ($exception instanceof \Illuminate\Session\TokenMismatchException) { 
     return response()->json('msg', 'Your session has expired. Please try again.'); 
    } 

你也可以傳遞一個新的csrf_token使用JSON一起,這樣就可以取代舊用新,並再次發送的形式要求。

if ($exception instanceof \Illuminate\Session\TokenMismatchException) { 
      return response()->json(['msg'=> 'Your session has expired. Please try again.', 'token'=> csrf_token()]); 
     } 

我還沒有測試過這段代碼。但是這應該讓你開始。

另外,如果你願意,你可以使用一個包:https://github.com/GeneaLabs/laravel-caffeine

+0

嘿,我做了什麼你已建議。請檢查我的代碼。另外,我相信laravel-caffeine目前只適用於php頁面上的表單而不是ajax表單。 –

+0

似乎對我來說沒關係。你試過這個代碼嗎?令牌不匹配是一項安全功能,因此這種方法也會爲任何試圖向服務器發送無效令牌請求的人打開大門。 –

+0

不起作用。嘗試第二次登錄也會產生相同的異常。其原因是後端的會話令牌再次刷新。你有更好的解決方案嗎? –

相關問題