, Rails. : , Javascript , , CSRF . :
linkToPost :: Route App -> [(Text,Text)] -> Text -> Widget
linkToPost = linkToMethod "POST"
linkToMethod :: Text -> Route App -> [(Text,Text)] -> Text -> Widget
linkToMethod method url attributes content =
toWidget [hamlet|
$newline never
<a href="@{url}" rel="nofollow" data-method="#{method}" *{attributes}>
|]
:
^{linkToPost CommentR [] "Create comment"}
Javascript data-method. rails.js, . Javascript:
$(document).ready(function() {
$(document).on("click", "a[data-method]", function() {
var link = $(this);
var method = link.data('method');
handleMethod(link);
return false;
});
});
function handleMethod(link) {
var href = link.attr('href'),
method = link.data('method'),
csrfToken = $('meta[name=csrf-token]').attr('content'),
form = $('<form method="POST" action="' + href + '"></form>'),
metadataInput = '<input name="_method" value="' + method + '" type="hidden" />';
if (csrfToken !== undefined) {
metadataInput += '<input name="_token" value="' + csrfToken + '" type="hidden" />';
}
form.hide().append(metadataInput).appendTo('body');
form.submit();
}
, POST _method, Yesod middleware _method, Rails. Javascript , .
CSRF-, Rails.js, CSRF <head>. -, CSRF defaultLayout:
mCsrfToken <- fmap reqToken getRequest
default-layout-wrapper.hamlet:
$maybe token <- mCsrfToken
<meta name="csrf-token" content=
CSRF, . , (, DELETE/users/1) CSRF, :
checkCsrf :: Handler ()
checkCsrf = do
((res, _), _) <- runFormPost (renderDivs (mempty :: AForm Handler () ))
case res of
FormSuccess _ -> return ()
_ -> permissionDenied "CSRF failure"
+ , .
Update
, Yesod CSRF cookie , , , , HTML . :
- cookie , HTML-.
- POSTing JSON/ .. , .
- Yesod