Retrofit_2 http POST返回403消息

时间:2017-12-05 04:11:40

标签: android http-post retrofit2 androidhttpclient

我试图将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消息。 我的代码在某处错了吗? 任何人都可以帮助我!感谢。

3 个答案:

答案 0 :(得分:0)

验证Key&amp;来自服务器的Sign标头。

  

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

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

如果你的api在邮递员中没有工作,那么在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);

答案 1 :(得分:0)

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

答案 2 :(得分:0)

根据请求添加标头 Content-Type:application / json

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