且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 Angular.js 和 iOS 客户端对 Node.js 应用程序进行身份验证

更新时间:2023-10-19 12:47:46

我将使用基于令牌的身份验证,您可以在每次请求时(自动)发送一个令牌.您必须登录一次,服务器将为您提供一个令牌,然后您可以使用该令牌随每个请求发送.此令牌将添加到 HTML 标头中,因此您不必修改对浏览器的每个请求.

I would use a token based authentication where you can send a token (automatically) with each request. You'll have to log in once, the server will provide you with a token which you can then use to send with each request. This token will be added to the HTML header, so that you don't have to modify each request to the browser.

您可以在 API 中设置某些调用,以便它们始终需要令牌,而其他调用可能不受令牌保护.

You can set certain calls in the API so that they always need a token, while others might not be token protected.

对于 Express,您可以使用 express-jwt (https://www.npmjs.org/package/express-jwt)

For Express, you can use express-jwt (https://www.npmjs.org/package/express-jwt)

var expressJwt = require('express-jwt');

// Protect the /api routes with JWT
app.use('/api', expressJwt({secret: secret}));

app.use(express.json());
app.use(express.urlencoded());

如果您想进行身份验证,可以在您的 express 服务器中创建此函数:

If you want to authenticate you can create this function in your express server:

app.post('/authenticate', function (req, res) {
  //if is invalid, return 401
  if (!(req.body.username === 'john.doe' && req.body.password === 'foobar')) {
    res.send(401, 'Wrong user or password');
    return;
  }

  var profile = {
    first_name: 'John',
    last_name: 'Doe',
    email: 'john@doe.com',
    id: 123
  };

  // We are sending the profile inside the token
  var token = jwt.sign(profile, secret, { expiresInMinutes: 60*5 });

  res.json({ token: token });
});

对于以/api 开头的受保护调用:

And for protected calls something that starts with /api:

app.get('/api/restricted', function (req, res) {
  console.log('user ' + req.user.email + ' is calling /api/restricted');
  res.json({
    name: 'foo'
  });
});

在您的 Angular 应用程序中,您可以使用以下方式登录:

In your Angular application you can login with:

$http
      .post('/authenticate', $scope.user)
      .success(function (data, status, headers, config) {
        $window.sessionStorage.token = data.token;
        $scope.message = 'Welcome';
      })
      .error(function (data, status, headers, config) {
        // Erase the token if the user fails to log in
        delete $window.sessionStorage.token;

        // Handle login errors here
        $scope.message = 'Error: Invalid user or password';
      });

并且通过创建身份验证拦截器,它会在每次请求时自动发送令牌:

And by creating an authentication interceptor, it will automatically send the token with every request:

myApp.factory('authInterceptor', function ($rootScope, $q, $window) {
  return {
    request: function (config) {
      config.headers = config.headers || {};
      if ($window.sessionStorage.token) {
        config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
      }
      return config;
    },
    response: function (response) {
      if (response.status === 401) {
        // handle the case where the user is not authenticated
      }
      return response || $q.when(response);
    }
  };
});

myApp.config(function ($httpProvider) {
  $httpProvider.interceptors.push('authInterceptor');
});

如果您必须支持不支持本地存储的旧浏览器.您可以将 $window.sessionStorage 与 AmplifyJS (http://amplifyjs.com/) 之类的库交换.例如,放大使用任何可用的本地存储.这将转化为如下内容:

If you have to support old browsers which do not support local storage. You can swap the $window.sessionStorage with a library like AmplifyJS (http://amplifyjs.com/). Amplify for example uses whatever localstorage is available. This would translate in something like this:

    if (data.status === 'OK') {
      //Save the data using Amplify.js
      localStorage.save('sessionToken', data.token);
      //This doesn't work on the file protocol or on some older browsers
      //$window.sessionStorage.token = data.token;
      $location.path('/pep');
    }
  }).error(function (error) {
    // Erase the token if the user fails to log in
    localStorage.save('sessionToken', null);
    // Handle login errors here
    $scope.message = 'Error: Invalid user or password';
  });

以及我们交换的 authintercepter:

And the authintercepter we swap for:

angular.module('myApp.authInterceptor', ['myApp.localStorage']).factory('authInterceptor', [
  '$rootScope',
  '$q',
  'localStorage',
  function ($rootScope, $q, localStorage) {
    return {
      request: function (config) {
        config.headers = config.headers || {};
        config.headers.Authorization = 'Bearer ' + localStorage.retrieve('sessionToken');
        return config;
      },
      response: function (response) {
        if (response.status === 401) {
        }
        return response || $q.when(response);
      }
    };
  }
]);

您可以在本文中找到除 AmplifyJS 之外的所有内容:

You can find everything except AmplifyJS in this article:

http://blog.auth0.com/2014/01/07/angularjs-authentication-with-cookies-vs-token/