Получение нового токена

234
12 апреля 2018, 14:27

Добрый день! Проблемка с авторизацией. Авторизация в приложении осуществляется по логину и паролю от личного кабинета на сайте. Так вот, после того, как юзер меняет пароль на сайте, то по уму после того как он заходит в приложение, то его должно выкинуть на окно авторизации, но этого не происходит, юзер может пользоваться приложением до тех пор, пока он сам не нажмет кнопку выйти, и только после этого он входит в приложение уже с новым паролем. Сохранение токена происходит с помощью SharedPreferences. Как сделать так, чтобы во время того, как пользователь видит SplashActivity, приложение получало новый токен(после смены пароля юзером в личном кабинете на сайте) и сравнивало с тем, что записано в SharedPreferences?

Сохранение токена при авторизации

      String token = user.getToken();
      SharedPreferences preferences = getSharedPreferences("common", MODE_PRIVATE);
      SharedPreferences.Editor editor = preferences.edit();
      editor.putString(SAVE_TOKEN, "" + token);
      editor.apply();
Answer 1

Если сервер даёт клиенту осуществлять запросы со старым токеном - это косяк самого сервиса

А для решения вашей проблемы в SplashActivity или где-то на старте можно выполнять наименее ресурсоёмкий запрос, который требует отправки токена для его подтверждения. Проверяете ответ: если он валидный, то пускаете дальше в приложение, если ошибка из-за неверного токена, то возврат на экран авторизации.

Answer 2

Вообще использовать share для хранения токенов/логинов/паролей идея так себе. На счет вашего вопроса - берете например Retrofit 2, пилите для него Interceptor и Factory как инъектор токена. в Interceptor проверяете ответ, если проблема авторизации тогда кидаете интент или exception, ловите в базовом классе Activity, от туда с clear task кидаете на форму логина или производите перелогин если логин/пароль сохранены

Код: Interceptor

public class AuthorizationInterceptor implements Interceptor {
private Context mContext;
private InternalRemoteRepository mRemoteRepository;
private Gson mGson;

public AuthorizationInterceptor(Context pContext, RemoteRepository pRemoteRepository, Gson pGson) {
    mContext = pContext;
    mRemoteRepository = (InternalRemoteRepository) pRemoteRepository;
    mGson = pGson;
}
@Override
@ParametersAreNonnullByDefault
public Response intercept(Chain chain) throws IOException {
    if (!Network.isNetworkAvailable(mContext)) {
        throw new NetworkException(mContext.getString(R.string.internet_connection_not_available));
    }
    Response response;
    try {
        response = chain.proceed(chain.request());
    } catch (Exception e) {
        throw new NetworkException(e.getMessage());
    }
    ResponseBody body = response.body();
    String bodyValue = body.string();
    if (!TextUtils.isEmpty(bodyValue)) {
        RPCResponse result = mGson.fromJson(bodyValue, RPCResponse.class);
        if (!result.isSuccess()) {
            switch (result.getErrorCode()) {
                case ERROR_USER_NOT_FOUND:
                case ERROR_USER_NOT_FOUND_AUTH:
                case ERROR_WRONG_PASSWORD:
                case ERROR_ACCOUNT_NOT_SUPPORT:
                    throw new AuthorizationException(result.getMessage(), result.getErrorCode());
                case ERROR_INVALID_ACCESS:
                case ERROR_ACCESS_TOKEN_NOT_FOUND:
                case ERROR_ACCESS_DIED:
                    mRemoteRepository
                            .reAuthorization()
                            .subscribe(success -> {
                                if (!success) {
                                    throw new AuthorizationException(result.getMessage(), result.getErrorCode());
                                }
                            }, pThrowable -> {
                                Intent intent = new Intent();
                                intent.setAction(AUTHORIZATION_FAILURE);
                                mContext.sendBroadcast(intent);
                            });
                    break;
                case ERROR_REFRESH_ACCESS_TOKEN:
                    mRemoteRepository
                            .refreshToken()
                            .subscribe(success -> {
                                if (!success) {
                                    mRemoteRepository
                                            .reAuthorization()
                                            .subscribe(resuccess -> {
                                                if (!resuccess) {
                                                    throw new AuthorizationException(result.getMessage(), result.getErrorCode());
                                                }
                                            }, pThrowable -> {
                                                Intent intent = new Intent();
                                                intent.setAction(AUTHORIZATION_FAILURE);
                                                mContext.sendBroadcast(intent);
                                            });
                                }
                            });
                    break;
                case ERROR_INTERNAL_SERVER:
                    throw new UnknownServerException(result.getMessage());
                default:
                    throw new UnknownException(result.getMessage());
            }
        }
    }
    return response
            .newBuilder()
            .body(ResponseBody.create(body.contentType(), bodyValue))
            .build();
}}

TokenInjector:

public class TokenInjectorFactory extends Factory {
private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
private TokenInjectorConverter TOKEN_INJECTOR_INSTANCE;
private AccountManager mAccountManager;
private Gson mGson;

public static TokenInjectorFactory create(AccountManager pAccountManager, Gson pGson) {
    return new TokenInjectorFactory(pAccountManager, pGson);
}
private TokenInjectorFactory(AccountManager pAccountManager, Gson pGson) {
    mAccountManager = pAccountManager;
    mGson = pGson;
    TOKEN_INJECTOR_INSTANCE = new TokenInjectorConverter();
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
    return TOKEN_INJECTOR_INSTANCE;
}
private class TokenInjectorConverter implements Converter<RPCRequest, RequestBody> {
    @Override
    @ParametersAreNonnullByDefault
    public RequestBody convert(RPCRequest value) throws IOException {
        Account[] accounts = mAccountManager.getAccountsByType(TOKEN_TYPE);
        if (accounts.length > 0) {
            try {
                value.setToken(mAccountManager.blockingGetAuthToken(accounts[0], TOKEN_TYPE, true));
            } catch (OperationCanceledException | AuthenticatorException pE) {
                throw new AuthorizationException();
            }
        }
        return RequestBody.create(MEDIA_TYPE, mGson.toJson(value));
    }
}}
READ ALSO
Java DateFormat.

Java DateFormat.

Какого вида должна быть дата, при dateStyle=2Не нашел ответа в JavaDocs

200
После клонировании: cannot load module file

После клонировании: cannot load module file

После клонирования проекта с github получил эту ошибку:

211
Android Studio засунуть сайт в приложение

Android Studio засунуть сайт в приложение

Всем привет, подскажите как засунуть сайт в приложение ? к примеру как тут http://wwwappsgeyser

225
Как добавить категории постов в проект? (какую использовать связь в БД)

Как добавить категории постов в проект? (какую использовать связь в БД)

Здравствуйте! Нужно добавить категории постов в проектНе могу представить, как нужно сделать связь, чтобы у каждого поста могли быть много...

182