Получение 401 несанкционированного в модернизации, но работает в Postman и Swift
брифинг перед "техническим материалом"
Не новичок в работе с Retrofit, но столкнулся с этим странным поведением, которое мне очень трудно понять и исправить,
У меня есть два веб-сервиса, оба работают нормально, как и ожидалось, в Postman и iOS, но только один работает в Retrofit, а не другой,
В свою защиту я могу сказать, что получаю (несанкционированный) ответ, а это значит, что я смог попасть на сервер и получить результат
В защиту разработчика API он говорит, что это работает в Postman и других устройствах так не проблема обслуживания
Если какой-либо специалист по модернизации там скажет мне, что модернизация может делать за моей спиной, чтобы получить эту ошибку?
ТЕХНИЧЕСКИЕ ВЕЩИ
Говоря о типе сервиса, он содержит разрешения на предъявителя маркер как заголовок, который истекает каждые 6 часов и не содержит никаких параметров вообще (так что это должно быть легко, верно ?) и простой url-адрес
http://hashchuna.nn-assets.com/api/locations
К сожалению, токен заголовка не может быть разделен с действительным ключом, потому что он будет истек, прежде чем кто-либо сможет его попробовать, но здесь это так или иначе разрешения на предъявителя 3d44626a55dbb024725984e0d37868336fd7e48a
ЧТО Я ПРОБОВАЛ
Я использую перехват okhttp, чтобы добавить заголовок авторизации для запроса, используя оба addHeader / header метод, нет пробелов в url, потому что нет r нет params
получение 401 несанкционированной ошибки в модернизации?
Java: Android: Retrofit-использование вызова, но, ответ{код = 401,message=unauthorized}
https://github.com/square/retrofit/issues/1290
Но не они помогли
предупреждение
Теперь сложная часть, чтобы иметь в виду, токен по истечении срока действия должен дать 401 ошибку, которая ожидается, но проблема даже для недавно созданного токена я получаю 401 , что является моей основной проблемой
LOG
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);
}
4 ответов
Я думаю, что вы переопределяете другие заголовки Retrofit
добавляет для вас, в результате чего ваш API не заботится о вашем Authorization
заголовок. Код ниже добавит заголовок к существующим заголовкам вместо их переопределения.
OkHttpClient mIntercepter = new OkHttpClient.Builder()
...
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("Authorization", "Bearer " + "1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e").build();
return chain.proceed(request);
})
...
.build();
формат этих заголовков и правильный здесь ключ должен быть Authorization
и значение должно быть Bearer 1ed6b7c1839e02bbf7a1b4a8dbca84d23127c68e
(в вашем случае).
решение
Благодаря некоторым советам, фактической причиной несовместимости сервиса является, предположительно, POSTMAN и iOS client store и reuse COOKIE
все само по себе, когда запросы сделаны без необходимости явной обработки, Cookie в Postman можно протестировать с помощью Почтальон Intercepter, но не может быть отредактирован, потому что chrome не позволяет редактировать cookie плагинами
однако Retrofit / OkHttp если не указано рассмотрит его отключено (возможно, по соображениям безопасности),
Cookie добавляется либо внутри Interseptor
как один из заголовков addHeader("Cookie","KEY-VALUE")
или
Использовать cookieJar
добавить в
OkHttpClient mIntercepter = new OkHttpClient.Builder()
.cookieJar(mCookieJar)
.addInterceptor(new RequestResponseInterseptor(context))
.addInterceptor(logInter)
.build();
на основе ваших потребностей и типа cookie
401 Unauthorized http://www.stackoverflow.com/api/login?email=test@test.com&password=123456
Date: Fri, 07 Apr 2017 11:23:28 GMT
Server: Apache/2.4.25 (Amazon) PHP/5.6.29
X-Powered-By: PHP/5.6.29
Cache-Control: no-cache, private
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
Content-Length: 41
Keep-Alive: timeout=5, max=100
Connection: Keep-Alive
Content-Type: application/json
{"msg":"Invalid Credentials"}
я столкнулся с проблемой, как это не удалось получить сообщение об ошибке.
когда сервер бросает ошибку, как 401
или другая ошибка, которую мы получаем null body
С сервера.Но вы можете получить сообщение об ошибке от сервера errorBody
String response = response.errorBody().string()
в моем случае, к сожалению, ни один из советов, перечисленных в решении @Ujju, не работал (т. е. ни заголовок "Cookie", ни CookieJar
applied). Единственное, что помогло мне, это просто замена addInterceptor
С addNetworkInterceptor
и все начинает работать.