Retrofit2 отправить токен на предъявителя - PullRequest
0 голосов
/ 07 апреля 2020

Я попытался отправить токен с HeaderMap, но получил ответ с кодом 401. Мой проект настроен так, что у меня есть отдельный файл для ApiClient, и у меня есть OkHttpClient Interceptor и HttpLoggingInterceptor, чтобы увидеть, что происходит, однако я не могу заставить работать токен на предъявителя. Я видел решения, которые добавляют его к перехватчику как заголовок в перехватчике, и я пробовал это, но так как мой токен сохранен в SharedPreferences, я не могу заставить его работать в классе ApiClient, который у меня есть.

Это ApiClient

HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

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

OkHttpClient okHttpClient = new OkHttpClient.Builder()
        .addInterceptor(new Interceptor() {
            @NotNull
            @Override
            public okhttp3.Response intercept(@NotNull Chain chain) throws IOException {
                Request originalRequest = chain.request();
                Request newRequest = originalRequest.newBuilder()
                //I would add the header here
                //I tried this but it says on "ApiClient.this" cannot be referenced from static context
                // .header("Authorization" , SharedPreferencesHelper.getUserToken(ApiClient.this));
                        .build();

                return chain.proceed(newRequest);
            }
        })
        .addInterceptor(interceptor)
        .build();

retrofit = new Retrofit.Builder()
        .baseUrl("http://192.168.0.6:8000/api/")
        .addConverterFactory(GsonConverterFactory.create())
        .client(okHttpClient)
        .build();

Это метод из SharedPreferencesHelper.getUserToken(MainActivity.this)

public static String getUserToken(Context context) {
    SharedPreferences sp = getSharedPreferences(context);
    return sp.getString(USER_TOKEN, null);
}

Это текущий вызов с ответом 401, если я не добавлю Accept => application / json URL-адрес ответа неверен и также возвращает страницу html, когда мне нужен простой ответ return response("LoggedOut", 200); //this is the response in the api

Map<String, String> headers = new HashMap<>();
headers.put("Accept", "application/json");
headers.put("Token", SharedPreferencesHelper.getUserToken(MainActivity.this));

Call<Void> call = apiInterface.LogoutUser(headers);

call.enqueue(new Callback<Void>() {
    // onResponse and onFailure here
}

Например, без заголовка Accept это ответ в LogCat

D/OkHttp: --> GET http://192.168.0.6:8000/api/logout
D/OkHttp: Token: wE1Y8IxJpwyXtvw0fYoXZAlQ6qCx24YtzonQIeJBQSHmNppe0Sn1kLYDgZKCw4MKbpab4Vspf61Nzer1
D/OkHttp: --> END GET
D/OkHttp: <-- 200 OK http://192.168.0.6:8000/login
//a bunch of html that's the web page at this route, notice the /api is missing 

Как я могу отправить это правильно?

РЕДАКТИРОВАТЬ: я использую Laravel проект для бэкэнда, и это соответствующий маршрут

Route::middleware('auth:sanctum')
    ->get('/logoutApi', function (Request $request) {

    $request->user()->tokens()->delete();

    return response("LoggedOut", 202);
});

1 Ответ

0 голосов
/ 07 апреля 2020

создать класс Authenticator, например:

const val HEADER_TOKEN_FIELD = "Authorization"
class ClassAuthenticator(
    private val pref: SharedPref
) : Authenticator {
    override fun authenticate(route: Route?, response: Response): Request? {

        return response.request().newBuilder()
                .header(HEADER_TOKEN_FIELD, pref.getToken())
                .build()
    }
}

, затем добавить перехватчик в вашем клиенте с помощью:

 val httpClient = OkHttpClient.Builder()
            .authenticator(ClassAuthenticator(pref))
            .addInterceptor { chain ->
                val request = chain.request()
                val httpRequest = request.newBuilder()
                        .addHeader(HEADER_TOKEN_FIELD, 
                          "Bearer ${pref.getToken()}")
                        .build()
                val response = chain.proceed(httpRequest)
                response
            }
            .build()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...