java - 具有基本 token 身份验证的 OkHttp 适用于 GET,但不适用于 DELETE

标签 java android rest nginx okhttp

我在 Android 上使用基本 jwt 身份验证连接到 REST 服务时遇到问题。我的 Android 代码使用 OkHttp 3 和 Retrofit 2。该服务器是在 AWS elasticbeanstalk 上运行的 node.js Hapi 服务器,具有默认的 nginx 代理配置。后端所做的就是检查每个调用的身份验证 token 。

问题:我的 GET 和 DELETE 都需要带有 token 的“Authorization” header 。当我使用 token 调用 GET 时,它起作用了。当我使用 token 进行 DELETE 操作时,我收到 403 ACCESS DENIED,但仅当 Android 设备连接到蜂窝网络并具有 ipv6 地址时。当它连接到我家的 Wi-Fi 时,它可以正常工作。

有关一些附加信息,直接连接到端口 8080 上的 Nodejs 服务器也可以使一切正常工作。我想将 nginx 保留在图中,以防我想在同一个机器上运行节点服务器的多个副本。另外,我对此很陌生,很乐意考虑任何替代方案。

这是 Android 代码:

    Gson gson = new GsonBuilder().create();

    OkHttpClient okClient = new OkHttpClient.Builder()
            .readTimeout(40, TimeUnit.SECONDS)
            .writeTimeout(40, TimeUnit.SECONDS)
            .addInterceptor(
                    new Interceptor() {
                        @Override
                        public okhttp3.Response intercept(Chain chain) throws IOException {
                            Request original = chain.request();

                            //auth token for every request
                            Request.Builder requestBuilder = original.newBuilder()
                                    .addHeader("Authorization", authToken);
                            Request request = requestBuilder.build();

                            // it correctly prints out header with the token for both GET and DELETE
                            Log.d("ApiManager", "HEADERS: " + request.headers().toString()); 

                            okhttp3.Response response = chain.proceed(request);
                            return response;
                        }
                    }).build();

    Retrofit retrofit = new Retrofit.Builder()
            .client(okClient)
            .baseUrl(MyApi.baseUrl)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .build();

    myApi = retrofit.create(MyApi.class);

以及我的 Nginx 设置:

upstream nodejs {
  server 127.0.0.1:8081;
  keepalive 256;
}

server {
  listen 8080;

  if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
      set $year $1;
      set $month $2;
      set $day $3;
      set $hour $4;
  }
  access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;
  access_log /var/log/nginx/access.log  main;

  location / {
      proxy_pass  http://nodejs;
      proxy_set_header   Connection "";
      proxy_http_version 1.1;
      proxy_set_header        Host            $host;
      proxy_set_header        X-Real-IP       $remote_addr;
      proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  }

  gzip on;
  gzip_comp_level 4;
  gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

}

更新:如果我将 Android 设备连接到 Wi-Fi 网络,它似乎可以工作,但如果我连接到蜂窝网络,它就不起作用。我被困住了。 从服务器上的nginx访问日志。它不会记录 403 错误:

  1. Android 设备已连接到蜂窝网络:IP: "2001:56a:6ffc:d07e:0:47:2e8a:4101, 142.59.70.25"GET 和 POST 请求有效,但 DELETE 无效。
  2. Android 设备已连接到 wifi:IP:“96.51.151.36”,GET、POST 和 DELETE 工作。

最佳答案

如果 POST 有效而 DELETE 无效,则尝试使用 HTTP 方法覆盖 X-HTTP-Method-Override header 或 _method 查询参数,看看是否有效它就是这样工作的。

如果它开始工作,那么您就会知道这是 HTTP 级别的问题(就像某些代理的问题)。如果没有,那么您就会知道这是您的路由处理程序的问题。

参见Common non-standard request fields在维基百科上。从长远来看,你是否想使用它是另一个问题,但它会让你快速缩小问题范围。

您没有发布任何后端代码,甚至没有说明后端使用什么框架,因此无法提供有关如何做到这一点的具体答案。如果您使用的是 Express,则可以使用 method-override中间件。

此外,在您发布的关于同一问题的其他问题之一中,您展示了 nginx 配置,似乎您所做的基本上是出于某种原因将流量从端口 8080 代理到 8081。尝试直接连接到 8081,以排除是您自己的代理导致问题的可能性。

(顺便说一句,如果您在一个问题中发布所有相关信息,而不是将其分散在关于同一问题的 3 或 4 个类似问题之间,会更容易。问题发布后可以进行编辑以添加更多信息. 请参阅:How do edits work 了解更多信息。)

关于java - 具有基本 token 身份验证的 OkHttp 适用于 GET,但不适用于 DELETE,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40851753/

相关文章:

javascript - BackboneJS 访问模型属性时出现问题

c# - 任何人都可以解释下面一段 Windows 匿名/恶作剧代码吗?

java - HTTPURLConnection 返回乱码

未找到用于 native 代码编译的 Android bitmap.h

java - 将链接更改为可在 TextView 上单击的自定义字符串

rest - grails 3覆盖queryForResource无法正常工作

java - Spring MVC - 使用 JSP 表删除 SQL 中的行

Java:在 Eclipse 中导出到 .jar 文件

java - 使用简单 XML 进行特殊解析 XML

java - 柱体改造2包括大括号