Android调用Django API时的CSRF及数据安全问题咨询
Hey there! Let's break down your questions one by one since you're getting started with Android + Django API development—totally get these can feel tricky at first!
1. How to get the CSRF token when submitting POST form data from Android?
Django's CSRF protection relies on matching a token stored in your app's cookie with one sent in the request headers. Here's a step-by-step approach:
- First, fetch the token via a GET request: Send a GET request to any Django endpoint protected by
CsrfViewMiddleware(like your app's homepage, or a simple dedicated endpoint you create just for this). This will trigger Django to set acsrftokencookie in the response. - Extract the cookie from the response: On Android, libraries like OkHttp make cookie handling easy. You can set up a
CookieJarto persist cookies between requests, then retrieve thecsrftokenvalue. Example code with OkHttp:// Set up a cookie jar to store cookies CookieJar cookieJar = new CookieJar() { private final HashMap<String, List<Cookie>> cookieStore = new HashMap<>(); @Override public void saveFromResponse(HttpUrl url, List<Cookie> cookies) { cookieStore.put(url.host(), cookies); } @Override public List<Cookie> loadForRequest(HttpUrl url) { List<Cookie> cookies = cookieStore.get(url.host()); return cookies != null ? cookies : new ArrayList<>(); } }; OkHttpClient client = new OkHttpClient.Builder() .cookieJar(cookieJar) .build(); // After making a GET request, extract the csrftoken String csrfToken = null; for (Cookie cookie : cookieJar.loadForRequest(HttpUrl.parse("https://your-django-api.com"))) { if (cookie.name().equals("csrftoken")) { csrfToken = cookie.value(); break; } } - Include the token in your POST request header: When sending your POST data, add a header named
X-CSRFTokenwith the token value you extracted.// Build your POST request body RequestBody body = new FormBody.Builder() .add("item_id", "123") .build(); Request request = new Request.Builder() .url("https://your-django-api.com/delete-item") .addHeader("X-CSRFToken", csrfToken) .post(body) .build();
Pro tip: Ensure CsrfViewMiddleware is enabled in your Django settings.py (it's on by default) so Django generates and validates the token correctly.
2. How to prevent POST data tampering (e.g., deleting item A instead of B)?
This is a critical security concern, but there are several robust ways to defend against it:
- Strict permission validation in Django: Never trust the data sent from the client alone. In your view, always verify the authenticated user has the right to modify/delete the specific resource. Example:
from django.shortcuts import get_object_or_404 from django.http import HttpResponseForbidden def delete_item(request, item_id): item = get_object_or_404(Item, id=item_id) # Check if the user owns the item before allowing deletion if item.owner != request.user: return HttpResponseForbidden("You don't have permission to delete this item") if request.method == "POST": item.delete() return HttpResponseRedirect("/items/") - Request signing: Generate a unique signature for each request on the Android side using a secret key shared only between your app and Django. Include this signature in the POST data, then have Django re-calculate the signature with the same key and parameters to confirm nothing was altered.
- Use HTTPS: Always encrypt all requests with HTTPS to block man-in-the-middle attacks from modifying data in transit.
- Avoid sequential resource IDs: Use non-sequential, random IDs (like UUIDs) for your database objects so attackers can't easily guess or modify IDs to target other resources.
- Add extra verification for critical actions: For destructive operations like deletion, you could require a secondary confirmation (e.g., a one-time token sent to the user's email or SMS) before executing the action.
3. Where does Django store the CSRF token? I didn't find it in the database.
Great question! CSRF tokens aren't stored as standalone records in your database—here's the breakdown:
- When a user first interacts with your Django app,
CsrfViewMiddlewaregenerates a unique CSRF token. This token lives in two places:- Client-side cookie: A cookie named
csrftokenis set on the user's device (in your Android app's cookie store). This cookie is sent automatically with every subsequent request to your Django API. - Django session: The token is also saved in the user's session. If you're using Django's default session backend (which stores sessions in the
django_sessiondatabase table), the token is part of the encryptedsession_datafield. You won't see it as plaintext when querying the table directly because Django encrypts session data by default.
- Client-side cookie: A cookie named
- When validating a POST request, Django checks that the
X-CSRFTokenheader value matches both the cookie value and the token stored in the session to confirm the request is legitimate.
内容的提问来源于stack exchange,提问作者Aishwarya

