android 改造后注销请求给出错误 406 不可接受:用户未登录。...在邮递员 api 上工作正常
Posted
技术标签:
【中文标题】android 改造后注销请求给出错误 406 不可接受:用户未登录。...在邮递员 api 上工作正常【英文标题】:android retrofit post logout request giving error 406 Not Acceptable : User is not logged in. ...on postman api works fine 【发布时间】:2017-11-07 09:09:38 【问题描述】:我正在使用 retrofit2 在 App 中注销,但每次它都会给出 error406 :不可接受:用户未登录。我正在使用改装定制 标头身份验证。这是我的代码:
退出代码
公共无效注销()
Log.v("checkTokenbefore",Constants.token);
OkHttpClient httpClient1 = new OkHttpClient.Builder().addInterceptor(new Interceptor()
@Override
public Response intercept(Interceptor.Chain chain) throws IOException
Request original = chain.request();
Log.v("checkLogin",Constants.token+Constants.username+Constants.password) ;
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Accept-Language","application/json").addHeader("content-type", "application/x-www-form-urlencoded")
.addHeader("API_KEY", "a5XSE8XCdsY6hAoCNojYBQ")
.addHeader("X-CSRF-Token",Constants.token)
;
Request request = requestBuilder.method(original.method(),original.body()).build();
return chain.proceed(request);
).build();
Retrofit retrofit1 = new Retrofit.Builder()
.baseUrl(Constants.API_BASE_URL)
.client(httpClient1)
.addConverterFactory(GsonConverterFactory.create())
.build();
ApiInterface restAPI1 = retrofit1.create(ApiInterface.class);
Call<Logout> callLogout = restAPI1.userLogout(Constants.token,Constants.username,Constants.password);
callLogout.enqueue(new Callback<Logout>()
@Override
public void onResponse(Call<Logout> call, retrofit2.Response<Logout> response)
Log.v("responseLogout",response.code()+"code"+response.errorBody().toString()+response.message()) ;
@Override
public void onFailure(Call<Logout> call, Throwable t)
);
虽然以下是登录代码,但效果很好:
public void loginQuestin()
//checkValidation ();
/*
ApiInterface apiService =
ApiClient.create(ApiInterface.class) ;*/
ApiInterface restAPI = retrofit.create(ApiInterface.class);
Call<UserAgain> call = restAPI.userLogin(mEmailAddress.getText().toString().trim(),
mPassword.getText().toString().trim());
call.enqueue(new Callback<UserAgain>()
@Override
public void onResponse(Call<UserAgain> call, Response<UserAgain> response)
Log.v("check",response.code()+"login"+response.body().getToken()) ;
//response.body().getU
Constants.username = mEmailAddress.getText().toString().trim() ;
Constants.password = mPassword.getText().toString().trim() ;
if (response.code()==200)
Log.v("checkAgain",response.code()+"login") ;
Constants.token = response.body().getToken() ;
startActivity(new Intent(LoginActivity.this, NavigationDrawerActivity.class));
@Override
public void onFailure(Call<UserAgain> call, Throwable t)
Log.v("check","failed");
t.printStackTrace();
);
//用于登录api调用的API/Http客户端
public class ApiClient
public static OkHttpClient httpClient = new OkHttpClient.Builder().addInterceptor(new Interceptor()
@Override
public Response intercept(Interceptor.Chain chain) throws IOException
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder() .addHeader("Accept-Language","application/json")
.addHeader("content-type", "application/x-www-form-urlencoded").addHeader("API_KEY", "a5XSE8XCdsY6hAoCNojYBQ")
;
Request request = requestBuilder.build();
return chain.proceed(request);
).build();
public static Retrofit retrofit = new Retrofit.Builder()
.baseUrl(Constants.API_BASE_URL)
.client(httpClient)
.addConverterFactory(GsonConverterFactory.create())
.build();
public static ApiInterface restAPI = retrofit.create(ApiInterface.class);
API接口类
@POST("token")
Call<Token> getToken();
@FormUrlEncoded
@POST("login")
Call<UserAgain> userLogin(@Field("username") String param1, @Field("password") String param2);
@FormUrlEncoded
@POST("logout")
Call<Logout> userLogout(@Field("username") String param1 , @Field("password") String param2);
Login APi 工作正常,响应代码为 200 OK 。在注销 api(客户端 xsrf 令牌)上使用添加的动态自定义标头时遇到的主要问题
参考: https://futurestud.io/tutorials/retrofit-add-custom-request-header api格式:
用户认证/登录
目的:- 用户登录 Rest URL:- /api/v1/people/login 方法:-POST 标头:接受-语言:应用程序/json API_KEY: a5XSE8XCdsY6hAoCNojYBQ 内容类型:application/x-www-form-urlencoded X-CSRF-Token:
用户注销
目的:- 用户注销 Rest URL:- /api/v1/people/logout 方法:-POST 标头:接受-语言:应用程序/json API_KEY: a5XSE8XCdsY6hAoCNojYBQ 内容类型:application/x-www-form-urlencoded X-CSRF-Token:正文中的参数:用户名:例如 service@test.com 密码:e.g. 123456
【问题讨论】:
【参考方案1】:使用拦截器添加动态 Header。
httpClient.addInterceptor((Interceptor.Chain chain) ->
Request originalRequest = chain.request();
设置 OAuth 令牌
Request.Builder newRequest = originalRequest.newBuilder();
newRequest.header("Authorization", accessToken).method(originalRequest.method(), originalRequest.body());
originalRequest = newRequest.build();
chain.proceed(originalRequest);
使用新令牌重复请求
Response response = chain.proceed(originalRequest); //perform request, here original request will be executed
if (response.code() == 401)
//if unauthorized
//perform all 401 in sync blocks
return chain.proceed(newRequest.build());
);
【讨论】:
我想我用过同样的东西参考链接:futurestud.io/tutorials/retrofit-add-custom-request-header 我想我正在使用的 XSRF 令牌存在一些问题,因为没有 API 调用工作以上是关于android 改造后注销请求给出错误 406 不可接受:用户未登录。...在邮递员 api 上工作正常的主要内容,如果未能解决你的问题,请参考以下文章
SpringMVC注解@RequestMapping之produces属性导致的406错误