Phalcon CSRF (跨網站偽造請求) protection
CSRF (cross site request forgery)特別對於表單的保護(尤其是登入頁面)很重要,在 Phalcon framework (3.x) 中可以參考以下範例(或者參考官方文件的 example)。
在登入頁面 (e.g. login.volt) 加上一個 hidden field,其 field name 與 field value 都是由 controller 產生給予。
<div class="container-fluid"> <div id="loginPanel"> {{ form("login/login", "method":"post", "autocomplete" : "off", "class" : "form-horizontal") }} <input type="text" class="form-control" id="username" name="user[username]" placeholder="Username"> <input type="password" class="form-control" id="password" name="user[password]" placeholder="Password"> <input type="submit" class="btn btn-default" id="login" value="Log In"> <input type="hidden" name="{{csrfTokenKey}}" value="{{csrfToken}}"> {{ link_to('login/forget', "password forgot?") }} </form> </div> </div>
然後在 controller 裏頭
<?php class LoginController extends ControllerBase { public function indexAction() { // restart a session $this->session->destroy(); $this->session->start(); // generate token for form forgery protection $this->view->csrfTokenKey = $this->security->getTokenKey(); $this->view->csrfToken = $this->security->getToken(); } public function loginAction() { if (!$this->request->isPost()) { $this->flashSession->error("Should be a form post"); return $this->response->redirect("login/index"); } // get the key of the last POST data element end($_POST); $key = key($_POST); if (!$this->security->checkToken($key, $_POST[$key], false)) { $this->flashSession->error("No form forgery"); return $this->response->redirect("login/index"); } // do other things // ... } }
比較要注意的是 security->getTokenKey() , security->getToken() , security->checkToken() 這三個 function call。官方文件在呼叫checkToke()時,是沒有傳任何參數,但實際上是等於拿 $_POST 資料的 tokenkey 跟 token 去做驗證 (如同上面的 sample code)。
Original link: Phanix's Blog