GitHub user dosubot[bot] added a comment to the discussion: update dataset via 
api from python - CSRF token

<!-- Greeting -->
Hi @mestachs! I'm [Dosu](https://go.dosu.dev/dosubot) and I’m helping the 
superset team.

<!-- Answer -->
Superset enforces CSRF protection on modifying API endpoints (like PUT to 
/api/v1/dataset/{id}) even when using Bearer JWT authentication, due to the 
@protect() decorator on those routes. This means you must include a CSRF token 
in your requests, not just the Authorization header with your JWT token 
[cite](https://github.com/apache/superset/discussions/35855).

To update a dataset via the API from Python, use requests.Session() to manage 
cookies, and follow this workflow:

1. Log in to get your access token.
2. Add the Authorization header to your session.
3. Fetch the CSRF token from /api/v1/security/csrf_token/ (with the 
Authorization header set).
4. Add the CSRF token to your session headers as X-CSRFToken.
5. Make your PUT request with the same session.

Example:

```python
import requests

session = requests.Session()

# 1. Login
login_resp = session.post(
    "https://your-superset/api/v1/security/login";,
    json={"username": "your_user", "password": "your_pass", "provider": "db"}
)
access_token = login_resp.json()["access_token"]
session.headers.update({"Authorization": f"Bearer {access_token}"})

# 2. Get CSRF token
csrf_resp = session.get("https://your-superset/api/v1/security/csrf_token/";)
csrf_token = csrf_resp.json()["result"]
session.headers.update({"X-CSRFToken": csrf_token})

# 3. Update dataset
resp = session.put(
    f"https://your-superset/api/v1/dataset/{dataset_id}";,
    json=dataset_payload
)
print(resp.json())
```

Do not manually set the Cookie header; let requests.Session() handle it 
[cite](https://github.com/apache/superset/discussions/35855).

If you get a 422 error from the CSRF endpoint about "Subject must be a string", 
make sure the 'sub' claim in your JWT is a string, not an integer 
[cite](https://github.com/apache/superset/issues/31675).

There is no supported way to disable CSRF for API endpoints using JWT Bearer 
tokens in Superset.


<!-- Dosu Comment Footer -->
*To reply, just mention [@dosu](https://go.dosu.dev/dosubot).*

---
<sup>How did I do? 
[Good](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=great_response)
 | 
[Irrelevant](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=irrelevant_answer)
 | 
[Incorrect](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=incorrect_sources)
 | 
[Verbose](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=too_verbose)
 | 
[Hallucination](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=hallucination)
 | [Report 
🐛](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=bug_report)
 | 
[Other](https://app.dosu.dev/response-feedback/f300ff59-3163-482d-835d-8cd9a8a01263?feedback_type=other)</sup>

[![Chat with 
Dosu](https://dosu.dev/dosu-chat-badge.svg)](https://app.dosu.dev/a28d3c7e-a9d3-459e-9fb6-3a6f9ff4f357/ask?utm_source=github)&nbsp;[![Open
 in 
Cursor](https://dosu.dev/dosu-in-cursor.svg)](https://cursor.com/link/prompt?text=Superset%20enforces%20CSRF%20protection%20on%20modifying%20API%20endpoints%20%28like%20PUT%20to%20/api/v1/dataset/%7Bid%7D%29%20even%20when%20using%20Bearer%20JWT%20authentication%2C%20due%20to%20the%20%40protect%28%29%20decorator%20on%20those%20routes.%20This%20means%20you%20must%20include%20a%20CSRF%20token%20in%20your%20requests%2C%20not%20just%20the%20Authorization%20header%20with%20your%20JWT%20token%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/discussions/35855%29.%0A%0ATo%20update%20a%20dataset%20via%20the%20API%20from%20Python%2C%20use%20requests.Session%28%29%20to%20manage%20cookies%2C%20and%20follow%20this%20workflow%3A%0A%0A1.%20Log%20in%20to%20get%20your%20access%20token.%0A2.%20Add%20the%20Authorization%20header%20to%20your%20se
 
ssion.%0A3.%20Fetch%20the%20CSRF%20token%20from%20/api/v1/security/csrf_token/%20%28with%20the%20Authorization%20header%20set%29.%0A4.%20Add%20the%20CSRF%20token%20to%20your%20session%20headers%20as%20X-CSRFToken.%0A5.%20Make%20your%20PUT%20request%20with%20the%20same%20session.%0A%0AExample%3A%0A%0A%60%60%60python%0Aimport%20requests%0A%0Asession%20%3D%20requests.Session%28%29%0A%0A%23%201.%20Login%0Alogin_resp%20%3D%20session.post%28%0A%20%20%20%20%22https%3A//your-superset/api/v1/security/login%22%2C%0A%20%20%20%20json%3D%7B%22username%22%3A%20%22your_user%22%2C%20%22password%22%3A%20%22your_pass%22%2C%20%22provider%22%3A%20%22db%22%7D%0A%29%0Aaccess_token%20%3D%20login_resp.json%28%29%5B%22access_token%22%5D%0Asession.headers.update%28%7B%22Authorization%22%3A%20f%22Bearer%20%7Baccess_token%7D%22%7D%29%0A%0A%23%202.%20Get%20CSRF%20token%0Acsrf_resp%20%3D%20session.get%28%22https%3A//your-superset/api/v1/security/csrf_token/%22%29%0Acsrf_token%20%3D%20csrf_resp.json%28%29%5B%22re
 
sult%22%5D%0Asession.headers.update%28%7B%22X-CSRFToken%22%3A%20csrf_token%7D%29%0A%0A%23%203.%20Update%20dataset%0Aresp%20%3D%20session.put%28%0A%20%20%20%20f%22https%3A//your-superset/api/v1/dataset/%7Bdataset_id%7D%22%2C%0A%20%20%20%20json%3Ddataset_payload%0A%29%0Aprint%28resp.json%28%29%29%0A%60%60%60%0A%0ADo%20not%20manually%20set%20the%20Cookie%20header%3B%20let%20requests.Session%28%29%20handle%20it%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/discussions/35855%29.%0A%0AIf%20you%20get%20a%20422%20error%20from%20the%20CSRF%20endpoint%20about%20%22Subject%20must%20be%20a%20string%22%2C%20make%20sure%20the%20%27sub%27%20claim%20in%20your%20JWT%20is%20a%20string%2C%20not%20an%20integer%C2%A0%5Bcite%5D%28https%3A//github.com/apache/superset/issues/31675%29.%0A%0AThere%20is%20no%20supported%20way%20to%20disable%20CSRF%20for%20API%20endpoints%20using%20JWT%20Bearer%20tokens%20in%20Superset.)&nbsp;[![Join
 Discord](https://img.shields.io/badge/join-5865F2?logo=discord&logoC
 olor=white&label=)](https://go.dosu.dev/discord-bot)&nbsp;[![Share on 
X](https://img.shields.io/badge/X-share-black)](https://twitter.com/intent/tweet?text=%40dosu_ai%20helped%20me%20solve%20this%20issue!&url=https%3A//github.com/apache/superset/discussions/36409)

GitHub link: 
https://github.com/apache/superset/discussions/36409#discussioncomment-15148909

----
This is an automatically sent email for [email protected].
To unsubscribe, please send an email to: 
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to