在 asp.net Web api 和 Angular js 中使用的身份验证方法

问题描述 投票:0回答:3

我正在使用 Web api 和 Angular js 创建 1 个网站,我对在我的网站中使用的身份验证感到非常困惑。

我创建了一个 login.js,其中有一个登录方法,它将把我的用户名/电子邮件 ID 和密码发布到我的 Web Api,并且 Web api 中的方法将验证该用户。

代码:

$scope.Login()
{
  $.post("api/Authentication/Login",Username,Password)
  {
  }
}

Web API 代码:

[Route]
Public Task<object> Login([FromBody] username,password)
{
   //method to authenticate user from database.
   //Now the tricky parts comes like after authenticating user should i 
   //just store the user id in my session like this Session["userid]=id or
   //Should i go for storing whole user object in my cookie as i have read 
   //that storing data in session is very bad idea and disaster too as session is very memory
   //and so i think i would go for cookie which will be saved on client side.
   //but what if cookie isnt supported by browser??
}
正如

Darin Dimitrov 在他的回答和评论中指出的那样,使用会话是灾难。 因此,我决定根据此答案使用 cookie,并且其中一个电子商务网站 Nop Commerce 也根据此问题和答案使用 cookie 来存储当前登录的客户对象问题

我遵循LukeP在这个Question中建议的代码用于身份验证目的,并在整个应用程序中维护当前的登录用户对象。

我也读过有关 asp.net 声明身份的内容,但不知道是否可以在我的 asp.net Web api 和 Angular js 中使用它。

那么任何人都可以告诉我在 asp.net Web api 和 Angular JS 中进行身份验证的正确方法是什么,以及在 LukeP 代码中要完成哪些更改才能使用 Web api 和 Angular JS??

任何人都可以向我解释一下我上面指出的这个方法,并提供一些详细描述和一些代码,因为它可以帮助我和其他一些人,如果他们正在寻找相同的东西。

稍后我将为解决上述所有代码问题的答案提供 100 赏金。

c# angularjs asp.net-web-api nopcommerce form-authentication
3个回答
4
投票

最好的方法是使用令牌身份验证。总而言之,它的工作原理如下:

    服务器上的
  • POST /api/login
     路由接受用户名 + 密码,检查它们对于数据库是否有效,然后生成并返回 
    refresh token
     (可以是随机字符串或 GUID)。 
    refresh token
     也存储在用户旁边的数据库中,覆盖之前的 
    refresh token
    
    服务器上的 
  • GET /api/access-token
  • 路由接受用户名 +
    refresh token
    ,检查它们在数据库中是否匹配,然后生成并返回
    access token
    任何其他
  • /api/*
  • 路由都需要在请求标头中包含有效的
    access token
    ,否则它们会假设用户没有有效的登录
    
    
    
access token

是使用只有服务器知道的密钥加密的数据对象。它应包含用户名、到期日期(通常从生成令牌后约 10 分钟)以及有关用户的任何权限或其他数据。因为它是用密钥加密的,所以攻击者无法伪造。


您需要在您的服务器上实现这些路由。

如果您使用 OWIN,则可以使用以下方法使用

Microsoft.Owin.Security.OAuth

NuGet 包为您进行加密:


将其添加到您的启动配置中:

using System.Web.Http; using Microsoft.Owin; using Microsoft.Owin.Security.OAuth; using Owin; [assembly: OwinStartup(typeof(MyProject.Startup))] namespace MyProject { public class Startup { public static OAuthBearerAuthenticationOptions OAuthBearerOptions { get; private set; } public void Configuration(IAppBuilder app) { var config = new HttpConfiguration(); OAuthBearerOptions = new OAuthBearerAuthenticationOptions(); app.UseOAuthBearerAuthentication(OAuthBearerOptions); // Configure Web API to use only bearer token authentication. config.SuppressDefaultHostAuthentication(); config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); app.UseWebApi(config); } } }

然后,你可以生成一个
ticket

(即未加密的

access token
)并像这样加密它:

var identity = new ClaimsIdentity(new[] { new Claim(ClaimTypes.Email, "users email"), // other business specific claims e.g. "IsAdmin" }); var ticket = new AuthenticationTicket(identity, new AuthenticationProperties( { ExpiresUtc = DateTime.UtcNow.AddMinutes(10) })); var accessToken = MyProject.Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket);

在 Angular 中,您需要设置一种登录方式、一种在过期时获取新 
access token

的方式,以及一种在每个 API 请求的标头中传递

access token
的方式。我建议将
refresh token
access token
存储在本地存储(或旧浏览器的 cookie)中,并使用
$httpProvider.interceptors.push
为每个
$http
调用添加拦截器。然后拦截器可以将访问令牌添加到标头,如下所示:
config.headers['Authorization'] = 'Bearer ' + accessToken;

以角度定义拦截器:

angular.module('app').service('authenticationInterceptor', ['$q', function($q) { this.request = function(config) { var accessToken = // ... get the access token from local storage / cookie config.headers['Authorization'] = 'Bearer ' + accessToken; return config; }; }]);

将其添加到
$httpProvider


angular.module('app').config(['$httpProvider', ($httpProvider: ng.IHttpProvider) => { $httpProvider.interceptors.push('authenticationInterceptor'); }]);



3
投票

我可以对你说的是 Outh2 的“令牌认证”应该可以完成这项工作;当我们谈论安全性时,这是使用 Angular 和 WebAPI 的最简单方法。在这种情况下,Cookie 不是正确的解决方案。

查看

this

文章,了解有关如何使用 ASP.NET Web API 2、Owin 和 Identity 实现完整的基于令牌的身份验证的更多详细信息。那篇文章在很多方面确实对我有帮助。最终,当您获得示例解决方案时,您可以返回此处并询问更多“详细信息”。 顺便说一句,我在你的代码中读到了这个“评论”:

//现在棘手的部分是在验证用户身份之后出现的,我应该这样做吗? //只需将用户 ID 存储在我的会话中,就像这样 Session["userid]=id 或 //我应该像我读过的那样将整个用户对象存储在我的cookie中吗

我个人认为session是邪恶的。我不是唯一的
一个

。 无论如何,如果你想在 web.api 世界中使用“session”,它不是免费的,你必须激活它。因此,如果出于任何原因您需要使用它,请选中this 希望有帮助:)


2
投票

Satellizer 是一个很棒的库,可以添加到您的 Angular 应用程序中

https://github.com/sahat/satellizer

HTML

<form method="post" ng-submit="login()" name="loginForm"> <div class="form-group has-feedback"> <input class="form-control input-lg" type="text" name="email" ng-model="user.email" placeholder="Email" required autofocus> <span class="ion-at form-control-feedback"></span> </div> <div class="form-group has-feedback"> <input class="form-control input-lg" type="password" name="password" ng-model="user.password" placeholder="Password" required> <span class="ion-key form-control-feedback"></span> </div> <button type="submit" ng-disabled="loginForm.$invalid" class="btn btn-lg btn-block btn-success">Log in</button> <br/> <p class="text-center text-muted"> <small>Don't have an account yet? <a href="/#/signup">Sign up</a></small> </p> <div class="signup-or-separator"> <h6 class="text">or</h6> <hr> </div> </form>

JS

angular.module('MyApp') .controller('LoginCtrl', function($scope, $auth) { $scope.login = function() { $auth.login($scope.user) .then(function() { toastr.success('You have successfully signed in!'); $location.path('/'); }) .catch(function(error) { toastr.error(error.data.message, error.status); }); }; });

	
© www.soinside.com 2019 - 2024. All rights reserved.