【问题标题】:Custom AngularJS $http interceptor case自定义 AngularJS $http 拦截器案例
【发布时间】:2016-08-06 13:46:22
【问题描述】:

最近我在我的网站上努力工作,前端使用 angularjs,后端使用 Symfony 3。我在后端放置了一个安全层,因此来自我的 FE 的每个请求都必须需要一个有效的令牌(使用 grant_type=client_credentials)。我已经阅读了有关使用 Angular 调用我的 API 后端的最佳实践的 looooot...标头我的不记名令牌。

所以,我有点困惑如何开始......因为一方面:

  • 我想调用我的后端以加载某些数据以在我的页面上使用以显示信息(使用 grant_type=client_credentials),并且,

  • 我也会有一个用户管理系统。因此,此用户必须使用用户名和密码登录(再次调用我的后端),但使用 grant_type=password...

真正的大问题是: 我可以用一个拦截器做同样的事情吗? (一个用于显示带有 grant_type=client_credentials 的页面元素数据,另一个用于普通用户?)

另一个问题是...如果尚未创建令牌,我可以使用此拦截器制作令牌吗(仅适用于页面信息,对于我想在令牌到期时刷新令牌的用户)?

对不起,如果有点困惑......我很困惑,我真的阅读了很多帖子,文档和帮助......但我不知道从哪里开始......我希望你能帮助我...... 谢谢大家。

【问题讨论】:

    标签: angularjs http symfony


    【解决方案1】:

    JWT 的美妙之处在于它们本质上只是 javascript 对象。例如,您可以为用户提供一个令牌,其中包含他们在系统中的角色(用户、管理员、支持等)并相应地显示/隐藏元素。 因此,基本上,您不仅授予用户访问 API 的权限,还为他们提供访问类型。当然,您永远不应该依赖客户端身份验证来直接允许受限 API(验证每个请求的令牌,检查服务器上提供的角色)。

    以下是 NodeJS 和 Angular 中的示例:

    //In NodeJS...
    app.get('/path/to/secured/api', verifyTokenOr401, function(req, res) {
    //Do stuff...
    res.json({msg: 'Success');
    });
    
    function verifyTokenOr401(req, res, next) {
     var authHeader = req.headers.authorization;
     try {
      var token = authHeader.split(' ')[1];
      if(jwt.verify(token, 'myAppSecret'))
       next();
     } catch(e) {
      res.status(401).send('Not authorized');
     }
    }
    
    //Assuming you use node-jsonwebtoken package
    app.post('/path/to/authentication', function (req, res) {
    //Verify authentication...
    
     User.findOne({username: req.body.username}).then(function(user) {
     //VerifyPassword
      if(!user)
       return res.status(401).send('No such user ' + req.body.username);
    
      if(!user.verifyPassword(req.body.password))
       return res.status(401).send('Wrong password for user ' + user.username);
    
     //Provide the user with the access token
      var token = jwt.sign({ subject: user.id, role: user.role }, 'myAppSecret');
      res.setHeader('Authorization', 'Bearer ' + token.toString());
      res.json(user);
     })
    .catch(function (e) { res.status(500).json(e); });
    });
    
    //In angular...
    .factory('jwtInterceptor', function() {
     return {
      request: function(config){
       var authHeader = config.headers('authorization');
       //Attach header if not present
       if(!authHeader)
        config.headers.authorization = 'Bearer ' + localStorage.get('myAppToken');
       return config;
      },
      response: function(response){
       //Look for token in the header if you get a response and save it
       var authHeader = response.headers('authorization');
       if(authHeader){
        try { localStorage.myAppToken = authHeader.split(' ')[1]; } catch(e) {}
       }
       return response;
      }
     }
    });
    

    值得注意的是:查看 auth0 对 NodeJSAngular 的存储库。两者都很棒。

    【讨论】:

    • 感谢朋友的回答!很清楚,但我不使用 NodeJS,因为托管在 apache 网络服务器上。
    • 这只是一个例子,但您可以将这个概念应用到任何后端
    • 谢谢我的朋友。我对 AngularJS 真的很陌生。您能帮我举一个基本示例,如何开始在我的项目中使用 JWT?
    • 我刚做了。您还需要配置后端。
    【解决方案2】:

    您可以创建一个服务,当 Angular 加载该服务时,会调用授权令牌并在标头中设置。通过这种方式,您无需在每次 Ajax 调用时设置令牌。你可以这样做:

    app.service("MyService", ["$http", function($http) {
        initialize();
    
        function initialize() {
            getAuthorizationToken().then(function(response) {
                $http.defaults.headers.common.Authorization = 'Bearer some_auth_code_here';
            });
        }
    
        function getAuthorizationToken() {
            // Get call for token
        }
    }]);
    

    【讨论】:

    • 谢谢我的朋友,我会试试这个......但是......这个例子没有必要使用 $http 拦截器?
    • 我使用了您的示例,但如果我尝试调用 API,我现在会收到错误:401(未经授权).. 我将 api 称为:$http.post("http://xxxxxxxx/api/method" ).then(function(response){...,我收到此错误。
    • 您可以尝试在登录时获取授权令牌并将其设置在标头中,以便进一步调用不需要设置令牌。
    猜你喜欢
    • 1970-01-01
    • 2021-06-15
    • 1970-01-01
    • 1970-01-01
    • 2019-02-11
    • 2014-05-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多