You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Retrofit2向Django API提交数据遇401错误求助

Troubleshooting 401 Unauthorized with Retrofit + Django API

Hey there! Let's figure out why your Android app is hitting a 401 error when POSTing to your Django API, especially since it works perfectly in Postman. The root cause here is almost always that your Retrofit client isn't sending the same authentication details that Postman is. Let's walk through the most likely fixes:

1. Verify Authentication Headers Are Set Correctly

Django APIs typically use either Token Authentication or Session/CSRF Authentication. Postman automatically handles things like cookies or saved tokens, but Retrofit needs explicit setup for this.

If You're Using Token Authentication

Most Django REST Framework setups use token auth. You need to add an Authorization header to every request. Update your ApiClient class to include an interceptor that injects this token:

public class ApiClient {
    public static final String BASE_URL = "https://myapilink.com/";
    private static Retrofit retrofit = null;

    public static Retrofit getClient(String authToken) {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(chain -> {
                    Request originalRequest = chain.request();
                    Request authenticatedRequest = originalRequest.newBuilder()
                            // Make sure there's a space after "Token"!
                            .header("Authorization", "Token " + authToken)
                            .method(originalRequest.method(), originalRequest.body())
                            .build();
                    return chain.proceed(authenticatedRequest);
                })
                .build();

        if (retrofit == null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(BASE_URL)
                    .client(okHttpClient)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

When you initialize your API service, pass in the token you've retrieved from your login flow.

If You're Using Session/CSRF Authentication

If your Django setup uses session auth (common with traditional Django views), you need to handle two things:

  • Persist session cookies between requests
  • Include the X-CSRFToken header in POST requests

First, set up a cookie jar to store session cookies:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .cookieJar(new CookieJar() {
            private final Map<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<>();
            }
        })
        .build();

Next, fetch the CSRF token before making your POST request (usually from a dedicated endpoint or the login response), then add it to your request headers:

Request authenticatedRequest = originalRequest.newBuilder()
        .header("X-CSRFToken", yourCsrfToken)
        .method(originalRequest.method(), originalRequest.body())
        .build();

2. Ensure Request Body & Content-Type Match Postman

Double-check that your Retrofit request is sending the same data format as Postman:

  • If you're sending JSON, use @Body with a model class and confirm GsonConverterFactory is added to your Retrofit builder.
  • If you're sending form data, use @FormUrlEncoded with @Field annotations instead of @Body.

Example JSON POST interface:

public interface DataApi {
    @POST("/api/your-endpoint/")
    Call<ApiResponse> submitData(@Body YourDataModel data);
}

Example form-data POST interface:

public interface DataApi {
    @FormUrlEncoded
    @POST("/api/your-endpoint/")
    Call<ApiResponse> submitData(
            @Field("field1") String value1,
            @Field("field2") int value2
    );
}

3. Rule Out Other Interferences

  • Check if any other OkHttp interceptors are modifying or removing your authentication headers.
  • Confirm your AndroidManifest includes the internet permission:
    <uses-permission android:name="android.permission.INTERNET"/>
    

Quick Debug Tip

Use OkHttp's logging interceptor to inspect the full request being sent. This will let you compare it directly to Postman's request details:

// Add this dependency first: implementation 'com.squareup.okhttp3:logging-interceptor:4.11.0'
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(loggingInterceptor)
        // Add your auth interceptor here
        .build();

This will print the full request headers and body in Android Studio's logcat—you'll immediately spot if the auth header is missing or incorrect.

内容的提问来源于stack exchange,提问作者Muhitun Azad Sohan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 04:17:40