GVKun编程网logo

使用Angular.js和iOS客户端对Node.js应用进行身份验证(angular nodejs)

23

在这篇文章中,我们将带领您了解使用Angular.js和iOS客户端对Node.js应用进行身份验证的全貌,包括angularnodejs的相关情况。同时,我们还将为您介绍有关Angular2/4ad

在这篇文章中,我们将带领您了解使用Angular.js和iOS客户端对Node.js应用进行身份验证的全貌,包括angular nodejs的相关情况。同时,我们还将为您介绍有关Angular 2/4 adal-angular4活动目录对API问题进行身份验证、Angular 2使用子路由进行身份验证、Angular 2使用本地ADFS进行身份验证、angularjs – Angular中的JWT身份验证 – 多个身份验证级别的知识,以帮助您更好地理解这个主题。

本文目录一览:

使用Angular.js和iOS客户端对Node.js应用进行身份验证(angular nodejs)

使用Angular.js和iOS客户端对Node.js应用进行身份验证(angular nodejs)

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

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

cookie

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

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

HTTP基本认证

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

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

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

OAuth

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

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

谢谢。

更新:

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

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

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

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

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

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

答案1

小编典典

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

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

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

var expressJwt = require(''express-jwt'');// Protect the /api routes with JWTapp.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: ''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开头的内容:

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/

Angular 2/4 adal-angular4活动目录对API问题进行身份验证

Angular 2/4 adal-angular4活动目录对API问题进行身份验证

我一直在按照这个例子从angular(4)应用程序访问azure活动目录: https://github.com/benbaran/adal-angular4-example

我可以对AD进行身份验证,但后来我想对在AD中注册的API / APP进行后续调用.

我试过用这个例子:

public CallAPI() {
  let headers = new Headers({ 'Content-Type': 'application/json' });
  var token;

  this.service.acquiretoken("{client id}").subscribe(p => {
    token = p;

    headers.append("Authorization",'Bearer ' + token);

    let options = new RequestOptions({ headers: headers });
    // Make the HTTP request:
    this.httpClient.get('https://localhost:45678/stuff',options).subscribe(data => {
      // Read the result field from the JSON response.
      this.results = data['results'];
      console.log(data);
    });

  },(error => {
    console.log(error);
  }));
}

我遇到的第一个问题是CORS错误.我在localhost上运行客户端应用程序:并获取:

XMLHttpRequest cannot load 07001. Redirect from ‘07001’ to ‘07003……….’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. Origin ‘07004’ is therefore not allowed access.

我尝试访问的app / API也在本地运行(客户端和服务器都是https)

它们都是活动目录中的已注册应用程序,其登录/应用程序ID uris设置为各自的本地主机地址.

app / api使用服务堆栈,因此设置:

app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
app.UseCookieAuthentication(new CookieAuthenticationoptions());
app.UseWindowsAzureActiveDirectoryBearerAuthentication(
  new WindowsAzureActiveDirectoryBearerAuthenticationoptions
  {
    TokenValidationParameters = new System.IdentityModel.Tokens.TokenValidationParameters
    {
      ValidAudience = Audience
    },Tenant = Domain
  });

public override void Configure(Container container)
{
  AddPreRequestFilters();
  AddErrorResponseFilters();

  this.Plugins.AddRange(ServiceConfiguration.GetPlugins());
  this.Plugins.Add(new SwaggerFeature());
  this.Plugins.Add(new CorsFeature(allowedHeaders: "Origin,X-Requested-With,Content-Type,Accept,Authorization",allowCredentials: true));
  ServiceConfiguration.Configure(container);

}

为了绕过CORS错误,我使用了Allow-Control-Allow-Origin chrome扩展,使用这个我得到一个OPTIONS请求,然后是302(到我的’stuff’端点),它包含我的授权:Bearer {token}标题.最后有一个OPTIONS和GET(带有auth标题)来登录.microsoft.com /…./ oath2 …

这总是无法登录.

我的ADAL配置如下所示:

const config: adal.Config = {                          
  tenant: 'xxxx.onmicrosoft.com',clientId: 'xxxxxxxxxxxxxx',// client id of AD app
  redirectUri: 'https://localhost:4200/',// the angular app
  cacheLocation: 'localStorage'

}

我有什么明显的遗失吗?我也尝试使用endpoints属性绕过acquiretoken步骤无济于事:

endpoints: {
  'https://localhost:45678/': 'https://localhost:45678/'   <-- the address of the API/APP I want to call
}

解决方法

我们(我们的高级开发人员)在登录AD(adal4.service.js)后尝试访问已注册的API时发现了一些问题

首先在handleWindowCallback中,在我们的情况下,requestType始终设置为UNKNowN,因此statematch始终为false.

这里有点黑客攻击:

if(requestInfo.requestType === 'UNKNowN') {
requestInfo.requestType = this.adalContext.REQUEST_TYPE.RENEW_TOKEN;
requestInfo.stateMatch = true;
}

我们还必须改变这个:

else if (requestInfo.requestType === 
this.adalContext.REQUEST_TYPE.RENEW_TOKEN) {
this.adalContext.callback = 
window.parent.callBackMappedToRenewStates[requestInfo.stateResponse];
}

对此:

else if (requestInfo.requestType === 
this.adalContext.REQUEST_TYPE.RENEW_TOKEN) {
this.adalContext.callback =
window.parent.callBackMappedToRenewStates[
decodeURIComponent(requestInfo.stateResponse)];
}

stateResponse中的url被编码(百分比符号等),因此永远不会匹配,使回调为null.

希望这有助于某人 – 也许找到更好的解决方案!

这是叉子:adal-angular4

Angular 2使用子路由进行身份验证

Angular 2使用子路由进行身份验证

我有一个角度2应用程序,我需要在每个页面上进行身份验证.所以我已经实现了一个自定义的RouterOutlet来确认我在每次更改页面时都已登录.
@Directive({
   selector: 'auth-outlet'
})
export class AuthOutlet extends RouterOutlet {
   publicRoutes: any;
   private parentRouter: Router;
   private authService: AuthService;
   constructor(_elementRef: ElementRef,_loader: DynamicComponentLoader,_parentRouter: Router,@Attribute('name') nameAttr: string,_authService: AuthService) {

      super(_elementRef,_loader,_parentRouter,nameAttr);
      this.parentRouter = _parentRouter;
      this.authService = _authService;
      this.publicRoutes = {
          'Login': true
      };
  }

  activate(oldInstruction: ComponentInstruction) {
      var url = this.parentRouter.lastNavigationAttempt;
      console.log('attemping to nav');
      if (!this.publicRoutes[url] && !this.authService.loggedIn){
          var newInstruction = new ComponentInstruction('Login',[],new RouteData(),Login,false,1);
          return super.activate(newInstruction);
      } else {
          return super.activate(oldInstruction);
      }
   }
}

这是一个有效的代码:
http://plnkr.co/edit/YnQv7Mh9Lxc0l0dgAo7B?p=preview

当用户未经过身份验证时,是否有更好的方法来拦截路由更改并重定向登录?

对于任何发现这一点的人来说,现在Angular 2中的答案是使用“Guards”作为新路由器的一部分.请参阅Angular 2文档:

https://angular.io/docs/ts/latest/guide/router.html#!#guards

一个基本的守卫只是实现“CanActivate”,并可以如下工作:

import {Injectable} from "@angular/core";
import {CanActivate,Router} from "@angular/router";
import {AuthService} from "../services/auth.service";

@Injectable()
export class AuthGuard implements CanActivate {
    constructor(private authService:AuthService,private router:Router){}

    canActivate(){
        if(this.authService.isAuthenticated())
            return true;

        this.router.navigate(["/login"]);
        return false;
    }
}

正如您在本示例中所看到的,我在其他地方运行了一个AuthService(实现并不重要),它可以告诉警卫用户是否已经过身份验证.如果有,则返回true,导航按常规进行.如果他们没有,我们返回false并将其重定向到登录屏幕.

Angular 2使用本地ADFS进行身份验证

Angular 2使用本地ADFS进行身份验证

我们决定使用Angular 2作为我们新项目的框架.在尝试处理事物的安全方面时,我在使用本地ADFS进行身份验证方面找不到多少.有很多处理Azure AD,但这不是我们的选择.
有谁知道一种方法能够设置Angular 2成功验证ADFS?
您可以使用ng2-adal npm library成功实现此功能,您可以像为Azure AD实现它一样实现它,而是使用ADFS值填充secret-service.js的值,如下所示:
import { Injectable } from '@angular/core';

@Injectable()
export class AdfsSecretService {
  private endpoints: any = {
    'http://{your-website-url}/':
    'http:/{the-service-provider-identifier}',// as registered in ADFS
  };

  public get adalConfig(): any {
    return {
        instance: 'https://{your.adfs.site}/',tenant: 'adfs',clientId: '{adfs-client-guid}',redirectUri: window.location.origin + '/',postlogoutRedirectUri: window.location.origin + '/',endpoints: this.endpoints
    };
  }
}

你可以在图书馆的自述文件部分找到一个例子的链接.

在ADFS方面,您需要在ADFS下注册您的应用程序作为应用程序组,有关更多信息,请参阅此technet article

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

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

您可以使用 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声明与调用任何函数所需的授权相匹配即将被召唤.

关于使用Angular.js和iOS客户端对Node.js应用进行身份验证angular nodejs的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Angular 2/4 adal-angular4活动目录对API问题进行身份验证、Angular 2使用子路由进行身份验证、Angular 2使用本地ADFS进行身份验证、angularjs – Angular中的JWT身份验证 – 多个身份验证级别等相关知识的信息别忘了在本站进行查找喔。

本文标签: