{"ok": true, "database": "docs", "table": "sections", "rows": [{"id": "upgrade_guide:what-you-can-remove", "page": "upgrade_guide", "ref": "what-you-can-remove", "title": "What you can remove", "content": "You can now delete any of the following from your plugins and custom templates: \n                     \n                         \n                             Hidden CSRF form fields: \n                             <input type=\"hidden\" name=\"csrftoken\" value=\"{{ csrftoken() }}\">\n \n                             The  csrftoken()  template helper (and  request.scope[\"csrftoken\"]()  for plugins that call it from Python) still exists as a compatibility shim. It now returns a per-request random string rather than a cookie-bound signed value. Datasette no longer validates this token, and no  ds_csrftoken  cookie is set. \n                             Important for plugin authors:  if your plugin previously used  request.scope[\"csrftoken\"]()  or the  ds_csrftoken  cookie as a security primitive (for example, signing a URL and later comparing it to the cookie), the invariant that the token equals  request.cookies[\"ds_csrftoken\"]  no longer holds. Replace those flows with signed, short-lived action URLs or explicit non-ambient credentials. \n                         \n                         \n                             Manual CSRF token extraction in tests, e.g.: \n                             # No longer needed\ncsrftoken = response.cookies[\"ds_csrftoken\"]\ncookies[\"ds_csrftoken\"] = csrftoken\npost_data[\"csrftoken\"] = csrftoken\n \n                             The  ds_csrftoken  cookie is no longer set at all. The  csrftoken_from=  argument of the Datasette test client's  .post()  method is now a no-op and can be removed from your test code.", "breadcrumbs": "[\"Upgrade guide\", \"Datasette 1.0a20 plugin upgrade guide\", \"CSRF protection is now header-based\"]", "references": "[]"}], "primary_keys": ["id"], "primary_key_values": ["upgrade_guide:what-you-can-remove"], "query_ms": 4.085997999936808, "truncated": false}