【问题标题】:Retrofit_2 http POST return 403 messageRetrofit_2 http POST 返回 403 消息
【发布时间】:2018-05-18 15:54:40
【问题描述】:

我正在尝试将 Java 源代码转换为 Android。这是执行 http POST 然后以 json 形式接收数据的 Java 代码。而且效果很好。

public String httpPost(){
String url = "https://webapi.com/api?" 
  List<NameValuePair> params; 
  List<NameValuePair> headers;

  params.add(new BasicNameValuePair("command", commandValue));
  params.add(new BasicNameValuePair("nonce", 
  String.valueOf(System.currentTimeMillis())));

  headers.add(new BasicNameValuePair("Key", API_KEY));
  headers.add(new BasicNameValuePair("Sign", SECRET_SIGNATURE);

  HttpPost post = new HttpPost(url);
        post.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8));
        String str = post.getEntity().toString();

        if (headers != null)
        {
            for (NameValuePair header : headers)
            {
                post.addHeader(header.getName(), header.getValue());
            }
        }

        HttpResponse response = httpClient.execute(post);
        HttpEntity entity = response.getEntity();
        if (entity != null)
        {
           return  EntityUtils.toString(entity);
        }

    return null;
   }

这是使用 Retrofit 2 的 Android 源代码:
APIServiceInterface.java

 @POST("api")
    Call<Mymodel> httpPost(@Header("Key") String key,
                                                 @Header("Sign") String sign,
                                                 @Query("command") String command,
                                                 @Query("nonce") String nonce);

APIClient.java

public class ApiClient {
    private static Retrofit retrofit = null;

    public static Retrofit getClient(String baseUrl) {
        if (retrofit==null) {
            retrofit = new Retrofit.Builder()
                    .baseUrl(baseUrl)
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
        }
        return retrofit;
    }
}

POST 请求

    String url = "https://webapi.com/";
    APIServiceInterface apiService =   ApiClient.getClient(url).create(APIServiceInterface.class);
    Call<MyModel> call = apiService.httpPost(apiKey, secretSignature, commandValue,  String.valueOf(System.currentTimeMillis()));
            call.enqueue(new Callback<MyModel>() {
                @Override
                public void onResponse(Call<MyModel> call, Response<MyModel> response) {
                    int statusCode = response.code();
                        Log.d(TAG,"http  POST:\n[header]:\n" + call.request().headers() +
                    "\n[request]:\n" + call.request().toString() +
                    "\n[body]: \n" + call.request().body().toString()+
                    "\n----------------------------------------------"+
                    "\nResponse:\n[header]:\n" + response.headers() +
                    "\n[body]:\n"+ response.body() +
                    "\n[raw]:" + response.raw() +
                    "\n[status] :" + response.code() +
                    "\n[message] :" + response.message());
                }

                @Override
                public void onFailure(Call<MyModel> call, Throwable t) {
                    // Log error here since request failed
                    Log.e(TAG, "Request failed :" + t.toString());
                }
            });   

这是调试日志

http  POST:
[header]:
Key: MHKVXY9C-9WE8N6CS-L1ETB10V-TFUA4S8G
Sign: 2534CCB0C58850B4FA621539D5AA5ACB0433B8F47070E6ED13757006F85FF1E4244D3118BDE107C46A7F5587C06BA201F74DE10003330ECBD352757D23E57ACA

[request]:
Request{method=POST, url=https://webapi.com/api?command=commandValue&nonce=nonceValue, tag=null}
[body]: 
okhttp3.RequestBody$2@1751ef1
----------------------------------------------
Response:
[header]:
date: Tue, 05 Dec 2017 07:07:50 GMT
content-type: text/html; charset=UTF-8
set-cookie: __cfduid=d0c467a5dbc10a660a569227616baa28f1512457670; expires=Wed, 05-Dec-18 07:07:50 GMT; path=/; domain=.webapi.com; HttpOnly
cf-chl-bypass: 1
cache-control: max-age=2
expires: Tue, 05 Dec 2017 07:07:52 GMT
x-frame-options: SAMEORIGIN
server: cloudflare-nginx
cf-ray: 3c852bb78ea732ef-HKG

[body]:
null
[raw]:Response{protocol=h2, code=403, message=, url=https://webapi.com/api?command=commandValue&nonce=nonceValue}
[status] :403
[message] :

但是 Android 源代码不起作用,它总是返回 403 消息。 我的代码是不是哪里错了?
谁能帮帮我!谢谢。

【问题讨论】:

  • 使用 logcat 提供完整错误
  • 我用调试日志更新了我的问题,请看一下。我认为帖子标题有问题,可能缺少某些东西但我还没有弄清楚。

标签: android http-post retrofit2 androidhttpclient


【解决方案1】:

根据要求添加标题 Content-Type: application/json

@Headers("Content-Type: application/json")
@POST("blue_lagoon_api/webservice/login")
Call<LoginResponse> callLoginApi(@Body LoginParameter loginParameter);

【讨论】:

    【解决方案2】:

    我认为您的凭据可能是正确的,但您从 CloudFlare 服务器(cloudflare-nginx)而不是从您的服务器(webapi)收到错误 403。 您的请求需要通过 cloudflare 实现

    【讨论】:

      【解决方案3】:

      首先从服务器验证 KeySign 标头。

      403 Forbidden 错误是一个 HTTP 状态代码,这意味着出于某种原因绝对禁止访问您尝试访问的页面或资源。

      验证您传递的标头和内容类型,然后在Postman 中进行测试,看看是否有效。

      如果您的 api 在 postman 中不起作用,那么您无法在 Android 中执行任何操作来使其起作用。


      更新

      尝试将标头与 http 客户端一起传递,

      httpClient.addInterceptor(chain -> {
              Request original = chain.request();
      
              // Request customization: add request headers
              Request.Builder requestBuilder = original.newBuilder()
                      .header("Key", API_KEY)
                      .header("Sign", SECRET_SIGNATURE);
                      .header("Content-Type", "application/json"); // set your content type
      
              Request request = requestBuilder.build();
              return chain.proceed(request);
          });
      
          Retrofit retrofit = builder.client(httpClient.build()).build();
      

      Post API 应该是

       @POST("api")
      Call<Mymodel> httpPost(
                             @Query("command") String command,
                             @Query("nonce") String nonce);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-06-19
        • 1970-01-01
        • 2021-03-21
        • 2014-09-15
        • 2023-01-31
        • 1970-01-01
        • 1970-01-01
        • 2015-10-23
        相关资源
        最近更新 更多