Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 29.12.2019, 12:25
Аспирант
Отправить личное сообщение для sniffysko Посмотреть профиль Найти все сообщения от sniffysko
 
Регистрация: 20.10.2009
Сообщений: 79

Правильно. Не работает. Поэтому есть 2 совета:
1. Вынести функцию isAuthenticated из гуарда в сервис юзеров. Это, так сказать, разделение ответственносте. Гуарды гуардят, а юзерсервисы юзерсервисят.
2. Проставление типов any облегчает жизнь нерадивому разрабу, но следующего по пути дзена просветляют и научает. Ибо, если бы у вас стоял не any, а Observable<User>, то вы бы поняли, что совать его в условный оператор бессмысленно. Функция асинхронная. Тут конечно вопрос: у вас пользователь, которого вы сравниваете в 17 строке где-то хранится локально? Если да, то и асинхрон не нужен. Если вы его читаете с сервера, то нужен. Но тут такая ситуация, ежли вы по каждому перемещению по роутам будете сервер дергать, то это очень не хорошо.
Итог:
1. isAuthenticated -- несем в изер сервис
2. Юзера читаем при инициализации и храним в том же юзер сервисе, либо создаем authService.
3. При перемещении по роуту избавляемся от асинхрона и выполняем обычные синхронные функции.
4. Если асинхронный подход нужен, то функцию isAuthenticated надо переписать под Observable.
5. Типизируем! Ангуляр довольно сложен, а типы помогут вам определиться с тем, что вы ожидаете получить. Если вас разочаровывают ошибки в процессе написания это говорит, что вы что-то не поняли и надо копать в этом направлении.
Ответить с цитированием
  #12 (permalink)  
Старый 30.12.2019, 11:31
Интересующийся
Отправить личное сообщение для Vadya Посмотреть профиль Найти все сообщения от Vadya
 
Регистрация: 15.04.2010
Сообщений: 24

Для меня это пока темный лес. Сохранил на потом, а пока хоть как-то сделать, но чтобы заработало.
Уже вторые сутки методом тыка пытаюсь вернуть логин из функции.

public isAuthenticated(): any {

this.userService.getUser().subscribe(data => (this.user = data));
// Здесь как то надо увидеть this.user.login

}
Ответить с цитированием
  #13 (permalink)  
Старый 30.12.2019, 13:37
Аспирант
Отправить личное сообщение для sniffysko Посмотреть профиль Найти все сообщения от sniffysko
 
Регистрация: 20.10.2009
Сообщений: 79

Сообщение от Vadya Посмотреть сообщение
Для меня это пока темный лес. Сохранил на потом, а пока хоть как-то сделать, но чтобы заработало.

public isAuthenticated(): any {

this.userService.getUser().subscribe(data => (this.user = data));
// Здесь как то надо увидеть this.user.login

}
Вы не ответили зачем вам асинхронный запрос. Асинхрон нужен только если вы лезете на бэк за данными пользователя. Асинхрон это не прерогатива сервисов, а типов запроса. Если пользователь хранится в сервисе, то:
Для Юзер сервиса дописываем функцию:
export class UserService{
    isAutentificated: boolean = false;
    userInfo: UserInfo

    constructor(
        http: HttpService
    ){}

    // Синхронная!
    isAuthenticated(): boolean {
       return this.isAutentificated;
    }

    // Асинхронная
    authUser(data: {login: string, password}){
        this.gttp.post('api/url').subscribe(
            (data: UserInfo) => {
                if(data){
                    this.userInfo = data;
                    this.isAutentificated = true;
                }
            }
        );
    }
}


authUser вызываем после того, как в форме логина вводим логин и пароль. Из компонента логина.
А теперь ваш код в гуарде:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> | boolean{
            if(this.userService.isAuthenticated()) { // Сейчас придет. Функция синхронная. 
                return true;
            } else {
                this.router.navigate(['/login']);
            }
   }


Если isAuthenticated все-же должен быть асинхронным, то подход другой.
Что-то типа такого (вы же понимаете, что и код функции isAuthenticated будет через обсерверы и не такой как в примере выше):
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean> | boolean{
            return this.userService.isAuthenticated()
               .subscribe( (data: boolean) => {
                    return data;
               });
   }


Что-то типа так. Пусть меня поправят более опытные товарищи. Пишу навскидку. Но смысл таков: если функция асинхронная, подписываемся на нее и полученный в подписке рузультат возвращаем. Когды вы выставите тыпы в вашем коде среда разработки подскажет вам какие функции можно вписать.
Ответить с цитированием
  #14 (permalink)  
Старый 30.12.2019, 15:12
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Это в userService
public isAuthenticated(): Observable<boolean> {    
	return this.getUser().pipe(
		map(data => !!data['login'])
	);
}

это в authGuard
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) : Observable<boolean>{
	return this.userService.isAuthenticated().pipe(
		tap((isAuthenticated: boolean) => {
			if (!isAuthenticated) {
				this.router.navigate(['/login'])
			}
		})
	);
}
Ответить с цитированием
  #15 (permalink)  
Старый 31.12.2019, 11:30
Интересующийся
Отправить личное сообщение для Vadya Посмотреть профиль Найти все сообщения от Vadya
 
Регистрация: 15.04.2010
Сообщений: 24

sniffysko, destus, огромное спасибо за примеры. Буду вникать поглубже, но теперь уже только после нг.
Если честно, то я даже не понимаю пока как оформлять функцию синхронной или наоборот. Жс у меня со скрипом всегда шел и понять его никак не могу. Вообще я делаю простую админку, не для массового использования, с целью познакомится с ангуляром. Это последнее из того что осталось сделать, чтобы был каркас, дальше уже думаю справлюсь самостоятельно. Я так вижу: мне нужена синхронная функция, так как проверка авторизации нужна только при переходе между страницами и при совершении каких-либо действий на сервере. Зачем асинхронная в данном случае не понимаю, но было бы интересно.
Всех фронтовиков с наступающим! И до новых встреч )
Ответить с цитированием
  #16 (permalink)  
Старый 03.01.2020, 09:56
Интересующийся
Отправить личное сообщение для Vadya Посмотреть профиль Найти все сообщения от Vadya
 
Регистрация: 15.04.2010
Сообщений: 24

Не актуально

А можете объяснить (неудобно наглеть, но желательно с примером), почему в этой конструкции не работает this.router.navigate(['/login']);
Там конечно легко накостылировать на ЖС, но хочется правильно все сделать
//  this.router.navigate(['/login']); // Тут работает
return this.userService.isAuthenticated().pipe(
            tap((isAuthenticated: boolean) => {
                if (!isAuthenticated) {
                    this.router.navigate(['/login']); // А тут нет
                } else {
                    return true;
                }
            })
);


В общем, как часто бывает, немного затупил - зацикливалось
Хотел сделать так: { path: 'login', component: LoginComponent, canActivate: [AuthGuard] }
Чтобы страницу логина было видно в canActivate и если авторизация есть, то переадресация на главную
return this.userService.isAuthenticated().pipe(
            tap((isAuthenticated: boolean) => {
                if (!isAuthenticated && route.url.join() != 'login') { // но почему-то это условие не срабатывает (&& route.url.join() != 'login'). Если нет авторизации бросает на страницу логина, а потом с нее же на нее. Это я так понимаю, а вообще в корень отправляет. Без ошибок в консоли
this.router.navigate(['/login']);
} else {
                    return true;
                }

Последний раз редактировалось Vadya, 05.01.2020 в 16:49.
Ответить с цитированием
Ответ


Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ajax запрос по логину и паролю должен получить xml данные olegalimov AJAX и COMET 23 30.01.2018 15:00
Получить данные из формы введенные за все время Michel Элементы интерфейса 1 13.10.2017 18:14
JQuery Autocomplete Как получить данные, вводимые пользователем в поле? decadent42 jQuery 7 30.10.2015 21:55
Как правильно получить введенные данные в поле? buket jQuery 11 11.04.2010 19:59
Возможно ли получить данные из файла на сервере? sdff Общие вопросы Javascript 11 19.07.2008 20:48