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

时间:2015-04-16 14:27:11

标签: angularjs sails.js jwt

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

我仍然在探究身份验证的确切工作方式,我目前正在尝试弄清楚如何添加多个授权级别。 它预先构建为0和1,我想在其上面添加一个管理级别。

它处理现有的授权级别,如下所示: 通过常量为每条路线分配授权级别。因此,所有用户路由都在状态的data属性中分配此访问属性:

    $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值放入用户模型中。但那又怎样?添加此功能和维护现有身份验证的完整性的最佳方法是什么(我担心安全性)?

2 个答案:

答案 0 :(得分:2)

您可以使用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”的添加策略,但验证所提供的JWT上的auth声明与调用任何即将被调用的函数所需的授权。

答案 1 :(得分:1)

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

我需要做一些事情来为我的angular / sails应用添加额外级别的身份验证:

  • 我必须在我的用户模型中添加“级别”字段。我使用的身份验证模块已经为匿名用户(0)和普通用户(1)设置了一些变量。所以现在我的用户模型存储你是1级还是2级。
  • 我必须更新角度应用中的相关常量,这些常量在执行某些身份验证时会被引用。我刚刚将admin: 2添加到现有的用户类型列表中。
  • 我必须在我的JWT中使用私有声明来将用户级别存储在其会话令牌中。这有必要确认用户在尝试做某事时通常具有他们所说的权限(通常是CRUD)。根据存储在其令牌中的权限级别检查其权限级别。这导致我必须做的下一件事......
  • 我必须创建两个策略。 Sails有一个整洁的配置结构,你可以在你的API中创建中间件(它称之为策略)。您只需使用您可能需要的任何中间件填充policies文件夹。然后在sails config文件夹中,有一个相应的policies.js文件,您可以在其中为每个控制器的每个特定功能分配中间件。很酷。所以我创建了一个中间件来检查以确保用户是他们所说的权限级别,另一个是确保他们是管理员(如果他们正在尝试管理员工作)。然后我只是将适当的中间件添加到我想要限制的任何函数中。
  • 如果有人登录,我有两个单独的仪表板以及普通用户无法访问的一些页面。因此,角度需要检查您是管理员还是仅仅是用户,并将您引导至相应的仪表板。我没有弄乱导航,而是在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函数处理。