Angular AuthGuard - 这是一个正确的解决方案吗?

Posted

技术标签:

【中文标题】Angular AuthGuard - 这是一个正确的解决方案吗?【英文标题】:Angular AuthGuard - is it a right solution? 【发布时间】:2019-09-17 10:11:57 【问题描述】:

我想创建一个路由守卫来保护路由免受未经授权的用户的攻击。

我正在使用 jsonwebtoken 进行授权,目前将其存储在 localStorage 中。

我的想法是,当用户想要访问受保护的管理员路由时,authguard 将验证令牌发送到 nodeJS/Express 服务器,验证后将 true 或 401(无论用户是管理员)返回到客户端。

认证服务:

isLoggedIn()
  let headers = new HttpHeaders().set('x-auth-token',localStorage.getItem('token') || '');
  return this.http.post('http://localhost:3000/api/users/check-auth', ,  headers: headers ).toPromise();

authGuard 服务:

canActivate()
    return this.sign.isLoggedIn().then(res => return res;).catch(ex => return ex);

我的目的是避免用户在本地存储中手动设置令牌密钥以查看受保护的路由,即使他无法实现任何 XHR 请求。

能否请您验证这是一个好主意还是坏主意,并在安全方面提出更好的解决方案? 非常感谢!

【问题讨论】:

我认为这是一个很好的做法,除了 401 响应。从技术上讲,客户端没有提出无效请求。 401 响应表明 HTTP GET 的 contents 无效。服务器应该产生 200 表示成功,并在正文中包含一个标志,客户端读取该标志以查看用户是否被允许。 401 错误作为错误请求记录在浏览器的控制台和网络面板中。 其实400表示http请求的内容无效。 401 确实是针对未经授权的请求。 谢谢,我会更正401响应。 :) 【参考方案1】:

一个好的做法是在服务器端的模型级别管理角色(或权限)。例如,一个用户类可以有一个角色属性,例如:

auth.service.ts
myUser.roles = ['ROLE_ADMIN']

这样,当您的用户登录时,您可以将信息存储在您的 auth.service.ts 中

// auth.service.ts
get isAdmin() 
    return this.user.roles.includes('ROLE_ADMIN')

请注意,通常您希望将此信息存储在您的应用状态管理中,无论是普通的 rxjs、ngrx、ngxs...

最后,您将添加一个 AuthInterceptor,如果您的 API 返回 401,它将重定向您的用户。

【讨论】:

权限在 mongoose 模型中定义,并包含在 jwt.如果我理解得很好,最好在客户端服务中存储登录用户的权限,对吧? 是的。每次您想要导航应用程序的受限区域时,您都不必向 API 发出请求。无论如何,您的应用程序的安全部分都将位于服务器端,并且由 jwt 实现。

以上是关于Angular AuthGuard - 这是一个正确的解决方案吗?的主要内容,如果未能解决你的问题,请参考以下文章

Angular 如何从 authguard 中检索?

Keycloak Angular 2 - 检查身份验证状态 Keycloak 对象

Angular AuthGuard - 它是一个正确的解决方案吗?

无法解析AuthGuard的所有参数:在我的AuthGuard服务中

无法使用具有来自 firebase 角色的 Angular AuthGuard

带有用户角色参数的 Angular2 路由 canActivate 和 AuthGuard (JWT)