Добрый день! Проблемка с авторизацией. Авторизация в приложении осуществляется по логину и паролю от личного кабинета на сайте. Так вот, после того, как юзер меняет пароль на сайте, то по уму после того как он заходит в приложение, то его должно выкинуть на окно авторизации, но этого не происходит, юзер может пользоваться приложением до тех пор, пока он сам не нажмет кнопку выйти, и только после этого он входит в приложение уже с новым паролем. Сохранение токена происходит с помощью 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();
Если сервер даёт клиенту осуществлять запросы со старым токеном - это косяк самого сервиса
А для решения вашей проблемы в SplashActivity
или где-то на старте можно выполнять наименее ресурсоёмкий запрос, который требует отправки токена для его подтверждения. Проверяете ответ: если он валидный, то пускаете дальше в приложение, если ошибка из-за неверного токена, то возврат на экран авторизации.
Вообще использовать 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));
}
}}
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
После клонирования проекта с github получил эту ошибку:
Всем привет, подскажите как засунуть сайт в приложение ? к примеру как тут http://wwwappsgeyser
Здравствуйте! Нужно добавить категории постов в проектНе могу представить, как нужно сделать связь, чтобы у каждого поста могли быть много...