英文:
How to Implement Angular Auth Guard
问题
我正在构建一个Angular应用程序。在这个应用程序中,我使用了身份验证守卫(Auth Guard)来保护应用程序。我是这样添加身份验证守卫的。
{ path: 'order', component: OrderComponent, canActivate: [AuthGuard]}
当我点击“Order”按钮时,如果用户未经身份验证,应该被重定向到登录页面。用户输入凭据后,应该重定向到“order”页面。
这是我的身份验证守卫实现。
import { Injectable } from '@angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService: AuthService, private router: Router) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): boolean {
let isLoggedIn = this.authService.isAuthenticated();
if (isLoggedIn) {
return true;
} else {
this.router.navigate(['/login']);
return false;
}
}
}
这是我的身份验证服务实现。
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
redirectUrl: string;
isLoggedIn = false;
constructor(private router: Router) {}
isAuthenticated() {
this.redirectUrl = this.router.url;
return this.isLoggedIn;
}
}
这是我的登录身份验证实现。
onClickSubmit() {
const headers = new HttpHeaders({authorization: 'Basic ' + window.btoa(this.loginData.email + ":" + this.loginData.password)});
this.httpClient.get("http://localhost:8181/authorize/", { headers, responseType: 'text' as 'json' })
.subscribe(
(response) => {
console.log(response);
this.router.navigate([this.authService.redirectUrl || '/order']);
},
(error) => console.log(error)
);
}
尽管如此,我仍然无法正确实现我的需求。
需求 - 当我点击“Order”按钮时,如果用户未经身份验证,应该被重定向到登录页面。用户输入凭据后,应该重定向到“order”页面。
英文:
I am building an Angular application. In this application, I used Auth Guard to secure the application. I added the Auth guard in the following way.
{ path:'order', component: OrderComponent, canActivate: [AuthGuard]}
When I click on Order If the user is not authenticated he should route to the login page. After the user enters his credentials user should redirect to the 'order' page.
Here is my Auth Guard implementation.
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot, Router} from '@angular/router';
import { Observable } from 'rxjs';
import { AuthService } from './auth.service';
@Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private authService:AuthService, private router: Router, state: RouterStateSnapshot){};
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
let isLoggedIn = this.authService.isAuthenticated();
if (isLoggedIn){
return true
} else {
this.router.navigate(['/login']);
return false;
}
}
}
And here is my Auth Service implementation.
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class AuthService {
redirectUrl: string;
isLoggedIn = false;
constructor(private router: Router) { }
isAuthenticated(){
this.redirectUrl = this.router.url;
return this.isLoggedIn;
}
}
And here is my login AUthentication implementation.
const headers= new HttpHeaders({authorization: 'Basic ' +window.btoa(this.loginData.email+":"+this.loginData.password)});
this.httpClient.get("http://localhost:8181/authorize/", {headers, responseType : 'text' as 'json'})
.subscribe(
(response) => {console.log(response);
this.router.navigate([this.authService.redirectUrl || '/order']);},
(error) => console.log(error));
}
Still, I was unable to properly implement my requirement.
Requirement - When I click on the Order button If the user is not authenticated he should route to the login page. After the user enters his credentials user should redirect to the 'order' page.
答案1
得分: 2
You can save original URL requested by the user in returnUrl
Auth Guard
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
Then use the returnUrl to navigate after login success
Auth Service
const returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
this.router.navigateByUrl(returnUrl);
英文:
You can save original URL requested by the user in returnUrl
Auth Guard
this.router.navigate(['/login'], { queryParams: { returnUrl: state.url }});
Then use the returnUrl to navigate after login success
Auth Service
const returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
this.router.navigateByUrl(returnUrl);
答案2
得分: 2
Login API Service返回Observable,因为http响应始终是异步的。这里不需要订阅!
isAuthenticated(): Observable<boolean> {
return this.httpClient.get("你的身份验证URL").pipe(
/* 运算符 - map,catchError - 根据需要 */
)
}
canActivate返回Observable给Router。Router在内部进行订阅,你不需要手动订阅。
export class AuthGuard implements CanActivate {
constructor(
private authService: AuthService,
private router: Router,
){};
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot) {
return this.authService.isAuthenticated().pipe(
map(auth => auth || this.router.parseUrl('/login')),
)
}
}
登录后,你可以在Login组件中重定向到/order。你可以在某个服务中保存返回路径,或将其附加到/login
路径作为参数。
英文:
Login API Service returns Observable, because http responses are always asynchronous. No subscription here!
isAuthenticated(): Observable<boolean> {
return this.httpClient.get("your auth url").pipe(
/* operators - map, catchError - as needed */
)
}
canActivate returns Observable to Router. Router internally subscribes, You don't need to subscribe.
export class AuthGuard implements CanActivate {
constructor(
private authService:AuthService,
private router: Router,
){};
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot) {
return this.authService.isAuthenticated().pipe(
map(auth => auth || this.router.parseUrl('/login')),
)
}
}
After login you can redirect to /order in Login component. You can save return path in some service or append to /login
path as parameter.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论