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

马修·帕尔默

我尝试阅读尽可能多的不同答案和帖子,但是我仍然不能完全满足自己的需求。我正在尝试找出最好的方法(最有效,但大多数情况下更安全)来处理用户身份验证,登录等。

我有一个运行在Express上的Node.js服务器;我有一个Angular.js网络应用程序;而且我有一个iOS应用。我使用Express / Node.js公开了RESTful API。

饼干

我读到的第一件事说使用cookie,并在服务器端(已哈希)和客户端(未哈希)存储会话id /登录令牌。客户端将随每个请求一起传输此ID,服务器将对其进行哈希处理,解析并相应地处理请求。这感觉不是RESTful的(不是一个大问题),但是更重要的是,我是否必须复制我的API:一个用于用户名/密码身份验证(例如,通过curl进行)和一个用于基于cookie的身份验证(例如,我的Web应用程序)?

另一个问题是:如果一个用户有多个连接,我该怎么办,例如,他们用两个浏览器(iPhone和iPad)登录。现在,我需要将其会话ID的存储空间存储为数组吗?

HTTP基本认证

下一个想法是使用HTTP基本身份验证(带有SSL),这似乎很容易,但是不建议您这样做,因为您需要在每个请求中都传送用户名和密码。如果我要使用HTTP Basic Auth进行操作,那么我是否会将用户名和密码存储在cookie(或HTML本地存储)中以允许“记住我”功能?还是我可以将两者结合起来:对实际请求使用HTTP Basic Auth(发布新帖子等),而仅将存储在cookie中的会话ID用于序列中的初始日志/还记得我方面吗?

传输会话ID是否比仅传输用户密码更安全?如何?会话ID表面上将充当密码,因此对我来说,传输它与传输密码具有相同的安全性问题。

似乎所有平台都支持基本身份验证,这是理想的选择。主要的缺点似乎是每个请求都需要传输客户端身份验证数据。有什么办法可以减轻这个问题?

OAuth

OAuth似乎对我的需求而言过于矫kill过正。我想我会失去执行curl命令来测试API的能力。OAuth与cookie方法相比有何改进?

您可能会说,我对可用的各种信息有些困惑,因此,如果您有一组适用于这种情况的良好链接,我希望阅读它们。我正在尝试找到适合所有平台的解决方案,但仍要尽可能地安全。另外,如果我的术语有误,请更正我,因为这会使我的搜索更加容易。

谢谢。

更新:

我一直在考虑这个问题,并且已经有了一个主意。请告诉我这是否是愚蠢的/不安全的/任何反馈,因为我不确定这是否好。

当用户登录时,我们会生成一个随机会话ID(加盐等)。这个可选的会话ID被发送给客户端,客户端可以选择将其存储(例如,存储在cookie中)。会话ID存储在数据库中。

然后,可以选择将该会话ID与每个请求一起作为HTTP身份验证标头或查询字符串发送,或者如果需要,客户端可以只发送用户名和密码(这为我们提供了常规的REST API)。在服务器端,我们首先检查会话ID参数,如果不存在,则检查用户名/密码。如果两者都不存在,那就是错误。

在服务器上,我们检查会话ID是否与正确的用户名相关联。如果是,我们将完成请求。

每次用户登录时,我们都会创建一个新的会话ID或删除当前的会话ID,并将其与响应一起发送至登录请求。

我认为这可以让我在适当的情况下使用带有Basic Auth的常规REST API,并维护会话/记住我的功能。它不能解决多个登录问题,但是我认为这种方式应该可以。请告诉我。

达恩·范·赫斯特

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

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

对于Express,您可以使用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());

如果要进行身份验证,可以在快递服务器中创建以下功能:

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: '[email protected]',
    id: 123
  };

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

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

对于受保护的呼叫,以/ api开头的内容:

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

在您的Angular应用程序中,您可以登录:

$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';
      });

通过创建身份验证拦截器,它将随每个请求自动发送令牌:

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 (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:

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之外的所有内容:

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

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

需要使用Web应用程序和Web API进行双重身份验证吗?

来自分类Dev

使用HTML客户端应用程序到ASP.Net Web API(MVC)进行表单身份验证

来自分类Dev

使用用户名和密码从WPF应用程序进行GitHub身份验证

来自分类Dev

从客户端应用程序使用Doorkeeper进行身份验证,而不传输秘密

来自分类Dev

在线SharePoint:Windows客户端应用程序可以使用OAuth进行身份验证吗?

来自分类Dev

Django Rest Framework + Angular.js Web应用程序中的用户身份验证

来自分类Dev

无法使用node.js对移动客户端进行身份验证(使用passport.js)

来自分类Dev

在同一MVC应用程序中同时使用OWIN Cookie身份验证和Windows身份验证

来自分类Dev

使用Active Directory进行身份验证的外部Rails / Node应用程序/ SSO

来自分类Dev

Angular JS SSL客户端身份验证

来自分类Dev

如何编写使用相互ssl身份验证的Java客户端和服务器应用程序?

来自分类Dev

对Node.js应用程序使用Firebase身份验证

来自分类Dev

使用LinkedIn的iOS 9 SDK通过Webview而不是LinkedIn的移动应用程序进行身份验证

来自分类Dev

从JS客户端在SignalR控制台应用程序上进行身份验证

来自分类Dev

使用Node.js Web应用程序中的用户名和密码在Azure AD上进行身份验证

来自分类Dev

如何使用oidc和Azure应用程序配置kubernetes以仅允许使用指定的安全组进行身份验证

来自分类Dev

如何获得使用带有客户端身份验证的客户端mvc应用程序的SignalR连接的用户的身份?

来自分类Dev

使用keycloak和openid_client对flutter应用程序进行身份验证

来自分类Dev

使用JAX-WS进行客户端应用程序身份验证

来自分类Dev

使用Devise进行Rails应用程序本地和远程身份验证(两种策略)

来自分类Dev

使用Windows身份验证和Web应用程序的IIS与Web应用程序

来自分类Dev

使用Jersey客户端对Spring Security Web应用程序进行身份验证时,我怎么了?

来自分类Dev

如何使用Node.js和NPM创建Web客户端应用程序(如angularjs教程)

来自分类Dev

使用OAuth对EWS应用程序进行身份验证

来自分类Dev

Azure移动应用程序和Xamarin表单:在后台使用Facebook进行身份验证

来自分类Dev

如何获取和使用适当的signingKey进行Azure移动应用程序身份验证?

来自分类Dev

如何在 OWIN 应用程序中使用 cookie 身份验证和 WsFederation 身份验证

来自分类Dev

使用 Ionic 应用程序进行 API 身份验证

来自分类Dev

使用 Google App Engine Node.js 应用程序配置基本 HTTP 身份验证

Related 相关文章

  1. 1

    需要使用Web应用程序和Web API进行双重身份验证吗?

  2. 2

    使用HTML客户端应用程序到ASP.Net Web API(MVC)进行表单身份验证

  3. 3

    使用用户名和密码从WPF应用程序进行GitHub身份验证

  4. 4

    从客户端应用程序使用Doorkeeper进行身份验证,而不传输秘密

  5. 5

    在线SharePoint:Windows客户端应用程序可以使用OAuth进行身份验证吗?

  6. 6

    Django Rest Framework + Angular.js Web应用程序中的用户身份验证

  7. 7

    无法使用node.js对移动客户端进行身份验证(使用passport.js)

  8. 8

    在同一MVC应用程序中同时使用OWIN Cookie身份验证和Windows身份验证

  9. 9

    使用Active Directory进行身份验证的外部Rails / Node应用程序/ SSO

  10. 10

    Angular JS SSL客户端身份验证

  11. 11

    如何编写使用相互ssl身份验证的Java客户端和服务器应用程序?

  12. 12

    对Node.js应用程序使用Firebase身份验证

  13. 13

    使用LinkedIn的iOS 9 SDK通过Webview而不是LinkedIn的移动应用程序进行身份验证

  14. 14

    从JS客户端在SignalR控制台应用程序上进行身份验证

  15. 15

    使用Node.js Web应用程序中的用户名和密码在Azure AD上进行身份验证

  16. 16

    如何使用oidc和Azure应用程序配置kubernetes以仅允许使用指定的安全组进行身份验证

  17. 17

    如何获得使用带有客户端身份验证的客户端mvc应用程序的SignalR连接的用户的身份?

  18. 18

    使用keycloak和openid_client对flutter应用程序进行身份验证

  19. 19

    使用JAX-WS进行客户端应用程序身份验证

  20. 20

    使用Devise进行Rails应用程序本地和远程身份验证(两种策略)

  21. 21

    使用Windows身份验证和Web应用程序的IIS与Web应用程序

  22. 22

    使用Jersey客户端对Spring Security Web应用程序进行身份验证时,我怎么了?

  23. 23

    如何使用Node.js和NPM创建Web客户端应用程序(如angularjs教程)

  24. 24

    使用OAuth对EWS应用程序进行身份验证

  25. 25

    Azure移动应用程序和Xamarin表单:在后台使用Facebook进行身份验证

  26. 26

    如何获取和使用适当的signingKey进行Azure移动应用程序身份验证?

  27. 27

    如何在 OWIN 应用程序中使用 cookie 身份验证和 WsFederation 身份验证

  28. 28

    使用 Ionic 应用程序进行 API 身份验证

  29. 29

    使用 Google App Engine Node.js 应用程序配置基本 HTTP 身份验证

热门标签

归档