Skip to content

Commit 51e1456

Browse files
committed
Исправление ошибок в блоке Аутентификация
1 parent 5af3031 commit 51e1456

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

cases/auth/Auth_article.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
## Аутентификация <br>
22
Думаю, что во многих приложениях, особенно в банковских, вы встречались со следующим поведением приложения: работаете, работаете, а потом вдруг появляется экран ввода пин-кода. Такое поведение обосновано мерами безопасности. Опишем данный процесс чуть более подробно с некоторыми техническими подробностями. <br>
3-
При старте приложения вам показывается экран с вводом пинкода. Вы посылаете запрос на сервер, и в случае успеха (верного пинкода) вам возвращается токен, и стартует сессия. Далее часть запросов вы шлете с использованием данного токена. Токен прикрепляется либо к заголовку запроса, либо к телу. Подобные запросы еще также называются запросами авторизованной зоны. То есть сессия - это время, в течении которого данный токен действителен на стороне сервера.<br>
3+
При старте приложения вам показывается экран с вводом пин-кода. Вы посылаете запрос на сервер, и в случае успеха (верного пин-кода) вам возвращается токен, и стартует сессия. Далее часть запросов вы шлете с использованием данного токена. Токен прикрепляется либо к заголовку запроса, либо к телу. Подобные запросы еще также называются запросами авторизованной зоны. То есть сессия - это время, в течении которого данный токен действителен на стороне сервера.<br>
44
Через какое-то время сессия завершается, обычно по истечению какого-то конкретного промежутка времени, и тогда токен "протухает". Запросы с протухшим токеном возвращают ошибку. Тогда либо нужно просто обновить токен специальным запросом, либо нужно пользователя снова перебросить на экран ввода пин-кода, обновить токен, и продолжить слать запросы авторизованной зоны с обновившимся токеном. <br>
55
А теперь представим, что подобное поведение вам необходимо реализовать в своем приложении. И архитектура вашего приложения - Чистая архитектура. <br>
66
Поэтому возникает ряд интересных вопросов: <br>
@@ -85,7 +85,7 @@ public class MainAuthenticator implements Authenticator {
8585
}
8686
```
8787
Благодаря добавлению ```synchronized``` к методу ```authenticate``` и блокирующему методу ```authHolder.refresh()``` мы добиваемся того, что при возникновении 401 ошибки мы первым делом идем обновлять токен. Все остальные запросы, которые возвращают 401 ошибку, тоже ждут обновления токена, и только после этого идут повторные запросы с обновленным токеном. Очень удобно!<br>
88-
Логичный вопрос. А как должен обновляться **AuthHolder**, через что он организизует свой запрос обновления токена. Так как опять-таки это внутренняя кухня организации работы с сервером, то Repositories и другие слои про это не знают. Это внутреннее дело **Data**. <br>
88+
Логичный вопрос. А как должен обновляться **AuthHolder**, через что он организует свой запрос обновления токена. Так как опять-таки это внутренняя кухня организации работы с сервером, то Repositories и другие слои про это не знают. Это внутреннее дело **Data**. <br>
8989
Хорошо, а через что тогда лучше осуществлять запрос? Через **CommonNetwork**, который будет включать классы для осуществления запросов неавторизованной зоны (запросов, не требующих токена). В [примере](https://github.com/AndroidArchitecture/AuthCase/tree/sample_1) эти классы объединены в **CommonNetworkModule**.<br>
9090
Обновленная схема приобретет вид:<br>
9191
![enter image description here](https://i.imgur.com/xvFKOZK.png)
@@ -280,7 +280,7 @@ public class AuthHolder {
280280
}
281281
```
282282
Обратим внимание на метод ```public void refresh()```. В нем мы обнуляем пинкод, сообщаем подписчику об истечении сессии, в данном случае сообщаем **AuthRepository**. Затем через обычный ```CountDownLatch``` мы блокируем поток до тех пор пока не будет вызван метод ```public void updatePinCode(@NonNull String pinCode)```. В данном методе приходит введенный пользователем пин-код (**синие стрелочки** на рисунке выше). <br>
283-
На всякий случай отмечу следующий момент. В данном случае обновление пин-кода - синхронная операция и выполняется она в главном потоке, поэтому с главного потока мы без проблем освобождаем поток, задержанный ```CountDownLatch```. Но если обновление пин-кода была бы асинхронной операцией, и выполнялась бы в другом потоке, то поток этот должен был браться не из ```Executors``` в **AuthNetwork**, иначе теоретически могло получиться, что все потоки были бы в режиме ожидания, и обновить пин-код было бы некому.<br>
283+
На всякий случай отмечу следующий момент. В данном случае обновление пин-кода - синхронная операция и выполняется она в главном потоке, поэтому с главного потока мы без проблем освобождаем поток, задержанный ```CountDownLatch```. Но если обновление пин-кода была бы асинхронной операцией, и выполнялась бы в другом потоке, то поток этот должен был браться не из ```Executors``` в **AuthNetwork**, иначе теоретически могло получиться, что все потоки были бы в режиме ожидания, и обновить пин-код было бы некому.<br>
284284
После того как пришел пин-код, поток, вызвавший ```refresh```, разблокируется и запускает запрос по обновлению токена (метод ```private Single<String> updateToken()```). В случае успешного обновления, остальные запросы с 401 ошибкой также перестартуются.<br>
285285
Конечно же, механизм по обновлению токена с ожиданиями через ```CountDownLatch``` вы можете переделать по своему усмотрению. В этом решении также могут быть не учтены некоторые крайние случаи. Тут важна опять-таки - концепция.<br>
286286
Вот собственно и все манипуляции =)

0 commit comments

Comments
 (0)