Angular 中的 JWT 身份验证 - 多个身份验证级别

JWT Authentication in Angular - Multiple authentication levels

我正在构建一个带有 sails.js 后端的 angular 应用程序。我已将此 JWT 身份验证合并到应用程序中。
https://github.com/Foxandxss/sails-angular-jwt-example

我仍在探索身份验证的确切工作原理,目前我正在尝试弄清楚如何添加多个授权级别。 它预装了 0 和 1,我想在其之上添加一个管理员级别。

它按如下方式处理现有的授权级别: 通过常量为每个路由分配一个授权级别。因此,所有用户路由都在状态中的数据 属性 处获得此访问权限 属性:

    $stateProvider
          .state('user', {
            abstract: true,
            template: '<ui-view/>',
            data: {
              access: AccessLevels.user
            }
          })

AccessLevels.user 是从常量键值对中提取的:

angular.module('app')
  .constant('AccessLevels', {
      anon: 0,
      user: 1
  });

每当导航到一条路线时,它都会检查 data.access 属性 以查看该特定路线的访问级别。如果它作为需要身份验证的路由返回,它会检查 localStorage 中的令牌。如果有令牌,路由将继续,否则它会启动你。

这是在 stateChangeStart 上调用的函数:

authorize: function(access) { //<- 'access' will be whatever is in the data property for that state
        if (access === AccessLevels.user) {
          return this.isAuthenticated(); // <- this just grabs the token
        } else {
          return true;
        }
      }

那么添加附加层的最简单方法是什么?
我显然需要将 auth_level 值放入用户模型中。但是然后呢?添加此功能并保持现有身份验证完整性的最佳方法是什么(我担心安全性)?

您可以使用private claims来保留服务器授予的权限。私人声明让您可以将任何其他类型的数据放入您想要的 JWT 中。

我从未使用过 node-jsonwebtoken(这似乎是 sails.js 用于 JWT 的),但看起来您可以直接使用 JWT 有效负载来访问您想要的值期待在场,所以你可以做这样的事情:

// Assign authorization on server after successful authentication of an admin
token.auth = AccessLevels.admin;

// Read authorization on client
authorize: function(access) {
    if (access === AccessLevels.anon) {
        return true;
    }
    // Assumes the JWT token is returned by isAuthenticated()
    // (Sorry, not familiar with Sails.js or the JWT example)
    return this.isAuthenticated().auth === access;
}

身份验证后,任何后续请求也应验证用户的授权,可能通过添加类似于您提供的示例中的 "tokenAuth" 的添加策略,但它会验证 auth 声明提供的 JWT 与调用任何将要调用的函数所需的授权相匹配。

首先,Erik Gillespie 让我朝着正确的方向前进。谢谢!

为了向我的 angular/sails 应用程序添加额外的身份验证级别,我必须执行以下操作:

  • 我必须向我的用户模型添加一个 'level' 字段。我正在使用的身份验证模块已经为匿名用户 (0) 和普通用户 (1) 设置了一些变量。所以现在我的用户模型存储你是1级还是2级。
  • 我不得不更新 angular 应用程序中的相关常量,该常量在执行某些身份验证操作时被引用。我刚刚将 admin: 2 添加到现有的用户类型列表中。
  • 我不得不在我的 JWT 中使用私有声明来将用户级别存储在他们的会话令牌中。这是必要的,以确认用户实际上拥有他们在尝试做某事时所说的权限(通常是 CRUD)。他们的权限级别根据存储在其令牌中的权限级别进行检查。这导致我必须做的下一件事...
  • 我必须制定两项政策。 Sails 有一个简洁的配置结构,您可以在 API 中创建中间件(它称之为策略)。您只需用您可能需要的任何中间件填充 policies 文件夹。然后在sails config文件夹中,有一个对应的policies.js文件,你可以在其中为每个控制器的每个特定功能分配中间件。很酷。所以我创建了一个中间件来检查以确保用户是他们所说的权限级别,另一个确保他们是管理员(如果他们试图做管理员的事情)。然后我只是将适当的中间件添加到我想要限制的任何功能中。
  • 如果有人登录,我有两个独立的仪表板以及一些普通用户无法访问的页面。例如,angular 需要检查您是管理员还是只是用户,然后将您定向到适当的仪表板。我没有弄乱我的导航,而是在 app.run 中创建了一个这样的函数:
        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
              if (toState.url == '/dashboard') {
                var dash = Auth.level(); // <- this is a service I made that checks the users level and returns the appropriate state to go to for that user
                event.preventDefault();
                $state.go(dash);
              }
    
    我添加了适合每种用户类型的任何路由,然后当他们点击 url 时,它会将他们推到正确的位置。我的路线也都附加了一个数据对象,指定访问所需的级别。因此,它会根据用户级别检查用户级别,以确保他们甚至可以访问应用程序的那部分。该 get 由类似的 stateChangeStart 函数处理。