Answers.Body: <p>as <a href="https://api.jquery.com/jquery.post/" rel="nofollow noreferrer">jQuery docs says</a> you have to pass data object or string via data.
  so you should change </p>
  
  <pre><code>var data = [];
  </code></pre>
  
  <p>to</p>
  
  <pre><code> var data = {};
  </code></pre>
  
  <p>in your code</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-04-02T20:33:15.627Z
Answers.LastActivityDate: 2020-04-02T20:33:15.627Z
Answers.UserDisplayName: user9975
Body: <p>Yes, it's another csrf question, the standard, <em>400 Error - Bad Request: Unable to verify your data submission.</em></p>
  
  <p>If in <code>config/general.php</code> I set <code>'enableCsrfProtection' =&gt; false,</code> then everything works nicely. So it's definitely a csrf problem.</p>
  
  <p>Here's the twig template for the widget:</p>
  
  <pre><code>src/templates/_components/widgets/Livestream_body.twig
  ---------------------
  &lt;script type="text/javascript"&gt;
      window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName|e('js') }}";
      window.csrfTokenValue = "{{ craft.app.request.csrfToken|e('js') }}";
  &lt;/script&gt;
  </code></pre>
  
  <p>and the Javascript:</p>
  
  <pre><code>src/assetbundles/livestreamwidget/dist/js/Livestream.js
  -------------------
  $(document).ready(function () {
     var data = [];
     data[window.csrfTokenName] = window.csrfTokenValue;
     $.post('actions/livestream/main/manage-get', data, function(response, textStatus, jqXHR) {
         alert('Posted OK!'); 
     });
  });
  </code></pre>
  
  <p>I can see the csrf token value changes on page load, and as I said, without csrf enabled, the js successfully loads the widget, so, what am I doing wrong on the csrf? I don't have any  element. Would that make a difference?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T19:27:06.530Z
Comments.Text: what happen if you wrap your js code in document.ready? maybe request is sent before variable assignment in twig?
Comments.UserDisplayName: user9975
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T19:31:51.977Z
Comments.Text: @user677900 Sorry, it is. I showed that in the question now.
Comments.UserDisplayName: kr37
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T19:36:48.537Z
Comments.Text: with developer tools in FF, can you see csrf param sent for that request and is it as same as window.csrfTokenValue and window.csrfTokenName in inspector tab?
Comments.UserDisplayName: user9975
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T19:48:42.650Z
Comments.Text: @user677900 I can see window.csrfTokenValue/Name but the params tab is blank. It says "No parameters for this request."
Comments.UserDisplayName: kr37
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T20:08:11.393Z
Comments.Text: I tried sticking the token in manually as a parameter to the post URL, like this, but it didn't help: `$.post('index.php?p=admin/actions/livestream/main/manage-get/&CRAFT_CSRF_TOKEN='+window.csrfTokenValue, data, function(response, textStatus, jqXHR) {...`
Comments.UserDisplayName: kr37
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T20:11:58.487Z
Comments.Text: i think in your posted code it has to be var data = {} not var data = []
Comments.UserDisplayName: user9975
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2020-04-02T20:29:25.813Z
Comments.Text: Thank you so much, kind person. I've been fighting with this for three days, and now it works! If you want to post a solution, I'll accept it.
Comments.UserDisplayName: kr37
Tags: <plugin-development><csrf><dashboard-widgets><cp-dashboard>
Title: CSRF in plugin dashboard widget 400 error
ThreadText: # CSRF in plugin dashboard widget 400 error
  
  (Asked by: username_0 on 2020-04-02)
  
  Yes, it's another csrf question, the standard, *400 Error - Bad Request: Unable to verify your data submission.*
  
  If in `config/general.php` I set `'enableCsrfProtection' => false,` then everything works nicely. So it's definitely a csrf problem.
  
  Here's the twig template for the widget:
  
  ```
  src/templates/_components/widgets/Livestream_body.twig
  ---------------------
  <script type="text/javascript">
      window.csrfTokenName = "{{ craft.app.config.general.csrfTokenName|e('js') }}";
      window.csrfTokenValue = "{{ craft.app.request.csrfToken|e('js') }}";
  </script>
  
  ```
  
  and the Javascript:
  
  ```
  src/assetbundles/livestreamwidget/dist/js/Livestream.js
  -------------------
  $(document).ready(function () {
     var data = [];
     data[window.csrfTokenName] = window.csrfTokenValue;
     $.post('actions/livestream/main/manage-get', data, function(response, textStatus, jqXHR) {
         alert('Posted OK!'); 
     });
  });
  
  ```
  
  I can see the csrf token value changes on page load, and as I said, without csrf enabled, the js successfully loads the widget, so, what am I doing wrong on the csrf? I don't have any element. Would that make a difference?
  
  **Tags:** plugin-development, csrf, dashboard-widgets, cp-dashboard
  
  > **Comments:**
  > **username_1**: what happen if you wrap your js code in document.ready? maybe request is sent before variable assignment in twig?  
  > **username_0**: @user677900 Sorry, it is. I showed that in the question now.  
  > **username_1**: with developer tools in FF, can you see csrf param sent for that request and is it as same as window.csrfTokenValue and window.csrfTokenName in inspector tab?  
  > **username_0**: @user677900 I can see window.csrfTokenValue/Name but the params tab is blank. It says "No parameters for this request."  
  > **username_0**: I tried sticking the token in manually as a parameter to the post URL, like this, but it didn't help: `$.post('index.php?p=admin/actions/livestream/main/manage-get/&CRAFT_CSRF_TOKEN='+window.csrfTokenValue, data, function(response, textStatus, jqXHR) {...`  
  > **username_1**: i think in your posted code it has to be var data = {} not var data = []  
  > **username_0**: Thank you so much, kind person. I've been fighting with this for three days, and now it works! If you want to post a solution, I'll accept it.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2020-04-02. Score: 2 | Accepted answer
  
  as [jQuery docs says](https://api.jquery.com/jquery.post/) you have to pass data object or string via data.
  so you should change
  
  ```
  var data = [];
  
  ```
  
  to
  
  ```
   var data = {};
  
  ```
  
  in your code
  
  
  ---
  
  