【发布时间】:2017-07-11 13:29:54
【问题描述】:
“技术资料”之前的简报
与 Retrofit 合作并不陌生,但遇到了这种奇怪的行为,我很难理解和修复,
我有两个 Web 服务,在 Postman 和 iOS 中都可以正常工作,但只有一个在 Retrofit 中工作,而另一个不能,
在我的辩护中,我可以说我收到了(未经授权的)响应,这意味着我能够访问服务器并获得结果
在 API 开发人员的辩护中,他说它适用于 Postman 和其他设备,因此不是服务问题
如果有任何改造专家告诉我,为了得到这个错误,我可能在背后做什么改造?
技术资料
谈到服务的类型,它包含 Authorization Bearer token 作为标头,每 6 小时过期一次,并且根本不包含任何参数(所以应该很简单,对吧?)和一个简单的网址
http://hashchuna.nn-assets.com/api/locations
不幸的是,标头令牌无法与有效密钥共享,因为它会在任何人尝试之前就过期,但无论如何Authorization Bearer 3d44626a55dbb024725984e0d37868336fd7e48a
我的尝试
我正在使用 okhttp 拦截来使用 addHeader/header 方法向请求添加授权标头,url 中没有空格,因为没有参数
Getting 401 unauthorized error in retrofit?
Java: Android: Retrofit - using Call but, Response{code = 401,message=unauthorized}
https://github.com/square/retrofit/issues/1290
但他们都没有帮助
警告
现在要记住的棘手部分是,过期的令牌必须给出预期的 401 错误,但问题是即使是新创建的令牌我也会得到 401 ,这是我的核心问题
日志
D/OkHttp: --> GET http://hashchuna.nn-assets.com/api/locations http/1.1
D/OkHttp: Authorization: Bearer 7c0d53de006b6de931f7d8747b22442354cecef9
D/OkHttp: --> END GET
D/OkHttp: <-- 401 Unauthorized http://hashchuna.nn-assets.com/api/locations (773ms)
D/OkHttp: Date: Mon, 20 Feb 2017 10:44:11 GMT
D/OkHttp: Server: Apache
D/OkHttp: X-Powered-By: PHP/7.0.15
D/OkHttp: Access-Control-Allow-Origin: *
D/OkHttp: Access-Control-Allow-Credentials: true
D/OkHttp: Access-Control-Max-Age: 1000
D/OkHttp: Access-Control-Allow-Headers: X-Requested-With, Content-Type, Origin, Authorization, Accept, Client-Security-Token, Accept-Encoding
D/OkHttp: Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
D/OkHttp: Expires: Thu, 19 Nov 1981 08:52:00 GMT
D/OkHttp: Cache-Control: no-store, no-cache, must-revalidate
D/OkHttp: Pragma: no-cache
D/OkHttp: Set-Cookie: PHPSESSID=u477o8g0q387t92hms4nhc14n1; path=/
D/OkHttp: Vary: Authorization
D/OkHttp: X-Powered-By: PleskLin
D/OkHttp: Keep-Alive: timeout=5
D/OkHttp: Connection: Keep-Alive
D/OkHttp: Transfer-Encoding: chunked
D/OkHttp: Content-Type: application/json;charset=utf-8
D/OkHttp: <-- END HTTP
代码
拦截
Request request = chain
.request()
.newBuilder()
//.header("Authorization","Bearer "+ SharedPrefsUtils.getSPinstance().getAccessToken(context))
.addHeader("Authorization","Bearer 1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e")
//.addHeader("cache-control", "no-cache")
//.cacheControl(CacheControl.FORCE_NETWORK)
.build();
改造实例
private Api getApiInstance(Context context) {
HttpLoggingInterceptor logInter = new HttpLoggingInterceptor();
logInter.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient mIntercepter = new OkHttpClient.Builder()
.addInterceptor(new RequestResponseInterseptor(context))
.addInterceptor(logInter)
.build();
Retrofit retrofitInstance = new Retrofit.Builder()
//.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.client(mIntercepter)
.build();
return retrofitInstance.create(Api.class);
}
【问题讨论】:
-
您确定将更新的令牌附加到您的标头吗?听起来您只是在使用旧令牌。
-
@C0D3LIC1OU5 是的,我知道这个问题听起来像是明显的错误,但事实并非如此,我什至在生成新令牌后就对其进行了硬编码,除非正在通过改造进行一些缓存,而我不是意识到
-
要仔细检查的另一件事是,您添加到标头的 KEY 与服务器期望的匹配,并且其中没有拼写错误。就像令牌值的“授权持有者”键(或您所称的任何内容)
-
这是干什么用的?
D/OkHttp: Set-Cookie: PHPSESSID=u477o8g0q387t92hms4nhc14n1; path=/ -
在 Postman 中,只接受
Authorization,当然我设置的值是Bearer 961e171e4d27c95f29a31c91cbef2d6863c760fe,但是,即使使用 Postman 仍然得到 401。您能否提供该 Web 服务的规范或要求文档?
标签: android ios retrofit postman okhttp