如何通过了解身份验证状态访问受保护的路由/禁用 Auth Guard
How to access protected routes / disable Auth Guard by knowing auth status
场景:
在这里,我正在构建一个应用程序,其中当前我有一个名为 products-info 的页面,其中 url 被发送给客户并单击 link 他可以直接打开该特定产品页面并查看信息,同一页面将出现在应用程序中。
问题 :
在这里,我使用 Auth guards 保护路由,因此如果不登录,用户将无法访问该页面。如果我通过电子邮件将同一页面 url 发送给用户,他应该只能查看该页面。
所以我的应用程序有:
- 登录页面
- 产品页面
- 产品信息页面
通常情况下,如果用户登录,此页面将可见,但是当管理员将 url 作为 mobiledot.com/products-info 发送到用户的电子邮件时,用户点击它并且应用程序不想登录并且它不想仅在该特定页面上显示任何注销或其他页面信息。下面是我的代码:
router.module.ts
const routes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'main/:role', component: MainComponent, canActivate: [RouteGuard] },
{ path: 'admin', component: AdminComponent},
{ path: 'user', component: userComponent,canActivate: [RouteGuard]}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [RouteGuard]
})
export class AppRoutingModule { }
auth 守卫
@Injectable()
export class RouteGuard implements CanActivate {
constructor(private service: accessService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
const isAllowed = this.service.getAuthenticated();
if (!isAllowed) {
this.router.navigate(['/']);
}
return isAllowed;
}
}
所以我也考虑了一些事情,比如用户是否登录到应用程序。我的路由器模块是:
if(user loginin){
{ path: 'main/:role', component: MainComponent, canActivate: [RouteGuard] },
}
else {
{ path: 'main/:token', component: MainComponent },
ex: www.mobiledot.com/product-info?toke="ssdsdsdsdSDSD"
}
有没有可能或者我们有什么其他办法吗?
简而言之,如果管理员通过电子邮件向用户发送受身份验证保护的应用程序中的相同页面 url,则用户将单击 link 并打开该页面,它应该不要求登录。
还有一个问题是关于localstorage
中存储的令牌。所以在移动之前,我们是否必须清除该令牌并放置一个新令牌以便它不会重定向到主页?
因为你有一个路由守卫,你需要一个即使你没有登录也应该 return true 的情况。
所以,你可以简单地使用你想到的方法www.mobiledot.com/product-info?toke="ssdsdsdsdSDSD"。
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
// check if there is a query param , like token in the url and url is your without token one.
if(queryParamToken && urlpath === 'view'){
// as you have token hit the api to check if required to check token is a valid one.
or can simply return true as per your need / requirement
-- checkout this link if you need referece
} else {
const isAllowed = this.service.getAuthenticated();
if (!isAllowed) {
this.router.navigate(['/']);
}
return isAllowed;
}
}
-- 如果需要参考,请查看此 link
你的意思是 products-info 应该对注册用户可见,因为他们可以在他们的电子邮件中收到相应的 link 而他们可能未经授权(可能是令牌过期)所以你需要一个解决方案来解决它。
首先,这是一种不好的做法 将 token
之类的东西显示为 Url 参数。所以避免它。
其次,请尝试采用正确的解决方案,而不是更改应用程序中的基本行为。 AuthGuard
旨在 决定是否可以激活路线 。它使用浏览器存储,如果令牌过期,您只能在过期之前刷新它,否则用户必须重新登录。
我的解决方案 正在创建类似于票证 ID 的东西,可以将其附加到已发送的 link(如 mobiledot.com/products-info/928f5f8b663571b7f3d829921c9079939c2d0319
)。您可以使其对用户一次性或多次有效。将其存储在数据库中并在用户使用时对其进行验证。这样就不用AuthGuard
只在服务器端控制内容权限了
场景: 在这里,我正在构建一个应用程序,其中当前我有一个名为 products-info 的页面,其中 url 被发送给客户并单击 link 他可以直接打开该特定产品页面并查看信息,同一页面将出现在应用程序中。
问题 : 在这里,我使用 Auth guards 保护路由,因此如果不登录,用户将无法访问该页面。如果我通过电子邮件将同一页面 url 发送给用户,他应该只能查看该页面。
所以我的应用程序有:
- 登录页面
- 产品页面
- 产品信息页面
通常情况下,如果用户登录,此页面将可见,但是当管理员将 url 作为 mobiledot.com/products-info 发送到用户的电子邮件时,用户点击它并且应用程序不想登录并且它不想仅在该特定页面上显示任何注销或其他页面信息。下面是我的代码:
router.module.ts
const routes: Routes = [
{ path: '', component: LoginComponent },
{ path: 'main/:role', component: MainComponent, canActivate: [RouteGuard] },
{ path: 'admin', component: AdminComponent},
{ path: 'user', component: userComponent,canActivate: [RouteGuard]}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
providers: [RouteGuard]
})
export class AppRoutingModule { }
auth 守卫
@Injectable()
export class RouteGuard implements CanActivate {
constructor(private service: accessService, private router: Router) {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
const isAllowed = this.service.getAuthenticated();
if (!isAllowed) {
this.router.navigate(['/']);
}
return isAllowed;
}
}
所以我也考虑了一些事情,比如用户是否登录到应用程序。我的路由器模块是:
if(user loginin){
{ path: 'main/:role', component: MainComponent, canActivate: [RouteGuard] },
}
else {
{ path: 'main/:token', component: MainComponent },
ex: www.mobiledot.com/product-info?toke="ssdsdsdsdSDSD"
}
有没有可能或者我们有什么其他办法吗?
简而言之,如果管理员通过电子邮件向用户发送受身份验证保护的应用程序中的相同页面 url,则用户将单击 link 并打开该页面,它应该不要求登录。
还有一个问题是关于localstorage
中存储的令牌。所以在移动之前,我们是否必须清除该令牌并放置一个新令牌以便它不会重定向到主页?
因为你有一个路由守卫,你需要一个即使你没有登录也应该 return true 的情况。
所以,你可以简单地使用你想到的方法www.mobiledot.com/product-info?toke="ssdsdsdsdSDSD"。
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean | Observable<boolean> | Promise<boolean> {
// check if there is a query param , like token in the url and url is your without token one.
if(queryParamToken && urlpath === 'view'){
// as you have token hit the api to check if required to check token is a valid one.
or can simply return true as per your need / requirement
-- checkout this link if you need referece
} else {
const isAllowed = this.service.getAuthenticated();
if (!isAllowed) {
this.router.navigate(['/']);
}
return isAllowed;
}
}
你的意思是 products-info 应该对注册用户可见,因为他们可以在他们的电子邮件中收到相应的 link 而他们可能未经授权(可能是令牌过期)所以你需要一个解决方案来解决它。
首先,这是一种不好的做法 将 token
之类的东西显示为 Url 参数。所以避免它。
其次,请尝试采用正确的解决方案,而不是更改应用程序中的基本行为。 AuthGuard
旨在 决定是否可以激活路线 。它使用浏览器存储,如果令牌过期,您只能在过期之前刷新它,否则用户必须重新登录。
我的解决方案 正在创建类似于票证 ID 的东西,可以将其附加到已发送的 link(如 mobiledot.com/products-info/928f5f8b663571b7f3d829921c9079939c2d0319
)。您可以使其对用户一次性或多次有效。将其存储在数据库中并在用户使用时对其进行验证。这样就不用AuthGuard
只在服务器端控制内容权限了