Я получаю ошибку токена CSRF при попытке обновления (или создания) записи. Я использую Elixir v1.0.3, Erlang/OTP 17 [erts-6.3] и Phoenix v0.8.0 (я думаю, я не уверен, как проверить версию Phoenix). Я создаю веб-приложение, в основном следуя инструкциям Phoenix и ресурсам примера Elixir Dose Jobsite. Однако, когда я пытаюсь опубликовать информацию из html-формы, я получаю ошибку токена CSRF. Следуя советам, приведенным в ошибке, я добавил «x-csrf-token»: csrf_token к действию.Phoenix - Неверная ошибка маркера CSRF (перекрестная защита)
edit.html.eex:
<h2>Edit Directory</h2>
<form class="form-horizontal" action="<%= directory_path @conn, :update, @directory.id, 'x-csrf-token': @csrf_token %>" method="post">
<div class="form-group">
<label for="directory" class="col-sm-2 control-label">Directory</label>
<div class="col-sm-10">
<input type="hidden" name="_method" value="PATCH">
<input type="text" class="form-control" value="<%= @directory.directory %>" name="directory" placeholder="Directory" required="required">
</div>
</div>
...
, но я получаю следующее сообщение об ошибке:
[error] #PID<0.579.0> running Ainur.Endpoint terminated
Server: localhost:4000 (http)
Request: POST /config/directories/2?x-csrf-token=
** (exit) an exception was raised:
** (Plug.CSRFProtection.InvalidCSRFTokenError) Invalid CSRF (Cross Site Forgery Protection) token. Make sure that all your non-HEAD and non-GET requests include the csrf_token as part of form params or as a value in your request's headers with the key 'x-csrf-token'
(plug) lib/plug/csrf_protection.ex:54: Plug.CSRFProtection.call/2
(ainur) web/router.ex:4: Ainur.Router.browser/2
(ainur) lib/phoenix/router.ex:2: Ainur.Router.call/2
(plug) lib/plug/debugger.ex:104: Plug.Debugger.wrap/3
(phoenix) lib/phoenix/endpoint/error_handler.ex:43: Phoenix.Endpoint.ErrorHandler.wrap/3
(ainur) lib/ainur/endpoint.ex:1: Ainur.Endpoint.phoenix_endpoint_pipeline/2
(plug) lib/plug/debugger.ex:104: Plug.Debugger.wrap/3
(phoenix) lib/phoenix/endpoint/error_handler.ex:43: Phoenix.Endpoint.ErrorHandler.wrap/3
Насколько я могу сказать (быть новым для эликсира, Феникс, и HTML), " действие "- это по существу путь, и любые параметры, которые я размещаю в нем, вернутся к приложению. И, действительно, я обнаружил, что x-csrf-token = "" передается обратно маршрутизатору, поэтому @csrf_token не может быть правильным. Я точно не знаю, откуда происходит csrf_token, поэтому я не знаю, как ссылаться на него (или, возможно, я делаю это совершенно неправильно).
Любые идеи были бы весьма признательны.
Благодарим вас за подробный ответ. Оказывается, я запускаю Phoenix 0.8.0, поэтому код ниже работает, но вы спасли мне большую головную боль, когда я обновляюсь до 0.9.0! –
Еще раз спасибо @ a4word, я обновился до Phoenix 0.9.0 и изменил шаблон, чтобы получить токен из файла cookie. Однако, как ни странно, он работает, но я все равно получаю недопустимую ошибку CSRF (Cross Site Forgery Protection). Токен является 'ne0GATpoc/EW6jbIbC7tmfkAWl4qb1opTPWmmfYFTRY =' (без пробелов), и шаблон создает URL-адрес 'POST/config/directories/9? X-csrf-token = ne0GATpoc% 2FEW6jbIbC7tmfkAWl4qb1opTPWmmfYFTRY% 3D' Я понятия не имею, почему Plug.CSRFProtection не нравится. Знаете ли вы, или я должен открыть другой вопрос? –
Я изменил имя маркера в шаблоне: ''x-csrf-token": Map.get (@ conn.req_cookies, "_csrf_token") 'to:' '_csrf_token': Map.get (@ conn.req_cookies) , "_csrf_token") 'и теперь это работает. –