在这篇文章中,我们将带领您了解使用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 2/4 adal-angular4活动目录对API问题进行身份验证
- Angular 2使用子路由进行身份验证
- Angular 2使用本地ADFS进行身份验证
- angularjs – Angular中的JWT身份验证 – 多个身份验证级别
使用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问题进行身份验证
我可以对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 }
解决方法
首先在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使用子路由进行身份验证
@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
当用户未经过身份验证时,是否有更好的方法来拦截路由更改并重定向登录?
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?
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身份验证 – 多个身份验证级别
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值放入用户模型中.但那又怎样?添加此功能和维护现有身份验证的完整性的最佳方法是什么(我担心安全性)?
我从未使用过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身份验证 – 多个身份验证级别等相关知识的信息别忘了在本站进行查找喔。
本文标签: