auth – Stepan Suvorov Blog https://stepansuvorov.com/blog Release 2.0 Thu, 02 Mar 2017 20:22:14 +0000 en-US hourly 1 https://wordpress.org/?v=6.3.1 Авторизация AngularJS. Right way. https://stepansuvorov.com/blog/2014/08/%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-angularjs-right-way/ https://stepansuvorov.com/blog/2014/08/%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-angularjs-right-way/#comments Fri, 15 Aug 2014 18:47:29 +0000 http://stepansuvorov.com/blog/?p=1622 Continue reading ]]>

Изучив кучу инструкций по сборке различных моделей велосипедов я таки собрал свой. Будет хорошо, если пост поможет сэкономить кому-то время на конструирование.

UPD: Статья обновлена и дополнена 2017-02-21

Отдельный модуль

Так как я сторонник модульного подхода и считаю, что именно это правильный способ использования AngualrJS, то весь функционал связанный с авторизацией я сложил в отдельный модуль auth. К нему подключаю модуль управления кукисами и модуль организации удобной работы с REST(restangular):

[javascript]angular.module(‘auth’, [‘ngCookies’, ‘restangular’]);[/javascript]

Сервис авторизации

Понятное дело, что какой бы вы самокат не делали, без сервиса не обойтись. Что в нем должно находиться? Делаем REST/token вариант авторизации, поэтому в сервисе будет следующий функционал:

  • авторизация по логину (асинхронная операция: POST запрос и получение/сохранения токена)
  • авторизация по токену (асинхронная операция: GET запрос и получение информации по пользователю)
  • проверка статуса (синхронная операция)
  • логаут (зачистка данных авторизации – токена)

Вот упрощенная версия кода(выкинул обработку ошибок):

[javascript]angular.module(‘auth’)
.service(‘AuthService’, function($cookies, $http, Restangular) {
‘use strict’;

var self = this;
this.status = {
authorized: false,
};

this.loginByCredentials = function(username, password) {
return Restangular.all(‘sessions’).post({ email: username, password: password })
.then(function(response) {
return self.loginByToken(response.contents);
});
};

this.loginByToken = function(token) {
$http.defaults.headers.common[‘X-Token’] = token;

return Restangular.all(‘sessions’).get(token)
.then(function(response) {
$cookies.accessToken = token;
self.status.authorized = true;
return response;
});
};

this.logout = function() {
self.status.authorized = false;
$cookies.accessToken = ”;

Restangular.all(‘sessions’).remove();
};
});[/javascript]

Приходится подключать $http сервис для вот этого хака:

[javascript]$http.defaults.headers.common[‘X-Token’] = token;[/javascript]

– по другому в Restangular не получается динамически задать хедер, в котором мы хотим отправлять токен авторизации.

(если у вас есть другое решение данной ситуации – пожалуйста поделитесь)

Страница авторизации

Если вы используете стандартный ангуляровский роутер, тут может возникнуть вопрос: Как для авторизации показывать другой лэйаут?

Решение подсказал Валентин Шибанов, который предложил завернуть все содержимое(в том числе ui-view) в ng-if, который бы в зависимости от того, авторизираван пользователь или нет, показывал бы либо содержимое с меню либо формочку авторизации.

Итого имеем(опять очень упрощенная версия):

[html]
<div ng-if="isAutorized">
<menu></menu>
<ui-view></ui-vew>
<div ng-if="!isAutorized">
<login></login>
</div>
[/html]

Плюшки с интерсепторами

Если переодически пропадает сессия с сервером(таймаут), но клиент остается активным, и вы хотите восстановить сессию без привлечения пользователя, можно посмотреть в сторону интерсепторов. Так же интерсепторы можно использовать для общей обработки ошибок авторизации.

Момент определения состояния авторизации и ограничение доступа

Давайте разберемся, в какой момент мы должны/можем проверять состояние авторизации. Все варианты можно условно разбить на 2:

  • ответ API (мы узнали от сервера)
  • изменение состояния (перешли на другую страничку)
    • событие изменение состояния
    • резолв конкретного стейта

Давайте посмотрим на все случаи.

Ответ от API и интерсептор для обратки ошибки

Про интерсепторы можно более подробно почитать тут. Мы с вами реализуем один из них интесептор ошибки ответа:

[javascript]
app.service(‘authRejector’, function($q) {
this.responseError = (rejection) => {
if (rejection.status === 401) {
//делаем какие-то действия для пользователя без авторизации
}

return $q.reject(rejection);
};
});
[/javascript]

и потом подключаем наш интерсептор к остальным:

[javascript]
app.config(function($httpProvider) {
$httpProvider.interceptors.push(‘authRejector’);
});
[/javascript]

Изменение стейта

Навесить хук в событие ui-router можно с помощью сервиса $transitions:

[javascript]
$transitions.onEnter({ to: ‘stateName’ }, function($state$, $transition$) {
if(!AuthService.status.authorized){
//делаем какие-то действия для пользователя без авторизации
return $q.reject()
}

}
[/javascript]

Запрет доступа к страница с помощью резолв

Давайте предлополжим, что у нас есть стейт users:

[javascript]
.state(‘users’, {})
[/javascript]

к которому мы хотим ограничить доступ. Для этого добавим резолв с использованием все того же сервиса авторизации:

[javascript]
.state(‘users’, {
resolve: {
auth: function($q, AuthService) {
if(!AuthService.status.authorized) {
$q.reject();
alert(‘Вы должны авторизироваться!’);
}
}
}
})
[/javascript]

Проверка авторизации при переходе на другую страницу

В ui-router мы можем навесить хук на событие перехода на какой либо стейт с помощью сервиса $transitions:

[javascript]
$transitions.onEnter({ to: ‘stateName’ }, function($state$, $transition$) {
if(!AuthService.status.authorized){
//делаем какие-то действия для пользователя без авторизации
return $q.reject()
}
}
[/javascript]

Но у приведем сам логин компонент для полноты примера.

Пример логин компонента

[javascript]
app.component(‘login’, {
controller: function(AuthService){
this.login = function(login, password)
AuthService.loginByCredentials(login, password).catch(function(){
//выводим ошибку авторизации
});
}
});
[/javascript]

 

]]>
https://stepansuvorov.com/blog/2014/08/%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-angularjs-right-way/feed/ 20
Автоматическая авторизация OpenVPN(не нужно вводить каждый раз пароль) https://stepansuvorov.com/blog/2013/01/%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b0%d1%8f-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-openvpn%d0%bd%d0%b5-%d0%bd%d1%83%d0%b6%d0%bd/ https://stepansuvorov.com/blog/2013/01/%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b0%d1%8f-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-openvpn%d0%bd%d0%b5-%d0%bd%d1%83%d0%b6%d0%bd/#respond Mon, 14 Jan 2013 07:03:42 +0000 http://stepansuvorov.com/blog/?p=884 Continue reading ]]> Как оказалось делается очень просто. Нужно дописать строчку в файл конфигурации (*.ovpn):

auth-user-pass authfile.crd

и потом создать сам файл authfile.crd со следующим содержанием:

user
password

И все больше пароль вводить не нужно.

Внимание! Должен напомнить о безопасности: при данной настройке( с сохранением пароля в открытом виде в файл) вы должны быть более чем на 100% уверены, что к нему не получит доступ другой человек.

]]>
https://stepansuvorov.com/blog/2013/01/%d0%b0%d0%b2%d1%82%d0%be%d0%bc%d0%b0%d1%82%d0%b8%d1%87%d0%b5%d1%81%d0%ba%d0%b0%d1%8f-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d1%8f-openvpn%d0%bd%d0%b5-%d0%bd%d1%83%d0%b6%d0%bd/feed/ 0
Настройка авторизации SSH через ключевую пару. https://stepansuvorov.com/blog/2012/08/%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d0%b8-ssh-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%83/ https://stepansuvorov.com/blog/2012/08/%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d0%b8-ssh-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%83/#comments Sat, 04 Aug 2012 08:27:57 +0000 http://stepansuvorov.com/blog/?p=382 Continue reading ]]> Столкнулся с необходимостью создания авторизации SSH основанной не на паролях, а на ключевой паре. Сюда выкладываю краткие заметки по процессу настройки(оказалось все довольно просто):

1. генерируем ключевую пару на стороне клиента:

$: ssh-keygen

причем в разных источниках предлагается использовать разные параметры для этой команды. Чаще всего предлагают использовать опцию type( флажок -t ) и туда записывать: rsa, dsa…; плюс есть вариант изменить размерность ключа с помощью флага -b и еще много других вариантов. На сколько я понял: можно использовать команду по умолчанию и не париться.

Мастер генерации ключевой пары еще задаст несколько вопросов, таких как: куда сгенерировать, нужен ли пароль на файл ключей. Тут тоже можно оставлять все по умолчанию.

2. Следующим шагом необходим скопировать наш открытый(public) ключ на сервер, куда мы хотим удаленно подключаться. Это опять же можно сделать простой командой на клиенте:

$: ssh-copy-id serveruser@serverhost

и если все прошло хорошо – выдаст где-то следующее:

Now try logging into the machine, with "ssh 'serveruser@serverhost'", and check in:

  .ssh/authorized_keys

to make sure we haven't added extra keys that you weren't expecting.

 

Приятных настроек!

 

P.S.: бывают случаи когда нет встроенной команды ssh-copy-id, тогда немного по другому:

# через scp копируем с клиента
$: scp ~/.ssh/id_rsa.pub serveruser@serverhost:/home/serveruse
# на сервере добавляем в список
$: cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
]]>
https://stepansuvorov.com/blog/2012/08/%d0%bd%d0%b0%d1%81%d1%82%d1%80%d0%be%d0%b9%d0%ba%d0%b0-%d0%b0%d0%b2%d1%82%d0%be%d1%80%d0%b8%d0%b7%d0%b0%d1%86%d0%b8%d0%b8-ssh-%d1%87%d0%b5%d1%80%d0%b5%d0%b7-%d0%ba%d0%bb%d1%8e%d1%87%d0%b5%d0%b2%d1%83/feed/ 1