2017-06-18 110 views
3

我的應用在這裏和那裏都有AJAX請求,我想用CSRF令牌來保護它們。然而,我不希望生成CSRF標記並將其傳遞給Twig渲染器以用於JavaScript中,而是希望在Twig呈現的每個HTML頁面中都可以使用CSRF標記。Symfony:使CSRF令牌可用於所有的樹枝模板

我已經看到Laravel似乎把它放在一個元標記中,所以我可以輕鬆地用JavaScript來獲取它。但是如何在Symfony中做到這一點?我如何在每個頁面中插入這個令牌?

或者這是不是很好的做法?

+0

你爲什麼需要這個? –

+0

我需要它來保護我的AJAX請求 – bluppfisk

+0

找到它,我可以在config.yml中插入tokenmanager作爲枝條全局變量,然後從模板中調用tokenmanager – bluppfisk

回答

1

當然,這是一個克實踐!

你在symfony/twig中有內置函數csrf_token('key')

例子:

<a href="{{ path('product_remove', {id: product.id, csrf: csrf_token('product') }) }}" 
    class="btn btn-info">Remove</a> 

從控制器,你只需要檢查:

/** 
* @Route("/product/remove/{csrf}/{id}", name="product_remove") 
*/ 
public function removeProductAction($csrf, $id) 
{ 
    if ($csrf !== $this->get('security.csrf.token_manager')->getToken('product')->getValue()) { 
     throw new InvalidCsrfTokenException('Invalid CSRF token'); 
    } 

    // delete $id 

    // cleans up url 
    return $this->redirectToRoute('product_list'); 
} 

all the things

+0

noooo〜你認真嗎?我整個下午都在搜索互聯網,並想插入服務,然後稱它很聰明。結果我所要做的就是在Twig中調用csrf_token()。不知道我是如何錯過它的。 rarr所有的東西。 編輯:我的意思是謝謝你! – bluppfisk

0

答案:將它作爲枝全局變量插入,然後使用Javascript將它綁定到所有請求。

config.yml

twig: 
    ## ... 
    globals: 
     csrfTokenManager: '@security.csrf.token_manager' 

base.html.twig

<script> 
    $.ajaxSetup({ 
     beforeSend: function(xhr) { 
      xhr.setRequestHeader('x-csrf-token', '{{ csrfTokenManager.getToken('ajaxAuth') }}'); 
    }); 
</script> 

接收控制器

public function receiveAction (Request $request) 
{ 
    $tokenManager = $this->get('security.csrf.token_manager'); 
    $tokenId = 'ajaxAuth'; 
    $token = new CsrfToken($tokenId, $request->headers->get('x-csrf-token')); 

    if (!$tokenManager->isTokenValid($token)) { 
     throw new HttpException(403, 'Go away h4x0r'); 
    } 
} 
+0

可以在任何地方使用相同的標識ID嗎?令牌id參數的含義是什麼,那麼如果它在任何地方都一樣? –