使用 webapi 进行 AngularJS 客户端路由和令牌身份验证 [英] AngularJS clientside routing and token authentication with webapi

查看:33
本文介绍了使用 webapi 进行 AngularJS 客户端路由和令牌身份验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 SPA angularjs 应用程序中创建一个用于身份验证和授权的示例,使用 asp.net mvc webapi 作为后端和客户端路由(无 cshtml).以下只是可用于设置完整示例的函数示例.但我不能把它放在一起.任何帮助表示赞赏.

I want to create an example for authentication and authorization in an SPA angularjs application using asp.net mvc webapi as the backend and client side routing (no cshtml). Below is just example of functions that can be used to set up the complete example. But I just can´t put it all togehter. Any help appreciated.

问题:

  1. 什么是最佳实践:基于 Cookie 还是基于令牌?
  2. 如何以 angular 创建不记名令牌以对每个请求进行授权?
  3. 验证 API 函数?
  4. 如何在客户端上保留登录用户的身份验证?

示例代码:

  1. 登录表单

  1. Sign in form

<form name="form" novalidate>
 <input type="text" ng-model="user.userName" />
 <input type="password" ng-model="user.password" />
 <input type="submit" value="Sign In" data-ng-click="signin(user)">
</form>

  • 认证角度控制器

  • Authentication Angular Controller

    $scope.signin = function (user) {
    $http.post(uri + 'account/signin', user)
        .success(function (data, status, headers, config) {
            user.authenticated = true;
            $rootScope.user = user;
            $location.path('/');
        })
        .error(function (data, status, headers, config) {
    
            alert(JSON.stringify(data));
            user.authenticated = false;
            $rootScope.user = {};
        });
    };
    

  • 我的 API 后端 API 代码.

  • My API backend API Code.

    [HttpPost]
    public HttpResponseMessage SignIn(UserDataModel user)
    {
        //FormsAuthetication is just an example. Can I use OWIN Context to create a session and cookies or should I just use tokens for authentication on each request? How do I preserve the autentication signed in user on the client?
        if (this.ModelState.IsValid)
        {
            if (true) //perform authentication against db etc.
            {
                var response = this.Request.CreateResponse(HttpStatusCode.Created, true);
                FormsAuthentication.SetAuthCookie(user.UserName, false);
    
                return response;
            }
    
            return this.Request.CreateErrorResponse(HttpStatusCode.Forbidden, "Invalid username or password");
        }
        return this.Request.CreateErrorResponse(HttpStatusCode.BadRequest, this.ModelState);
    }
    

  • 授权使用 JWT 库限制内容.

  • Authorization Using the JWT library for restricting content.

    config.MessageHandlers.Add(new JsonWebTokenValidationHandler
    {
      Audience = "123",
      SymmetricKey = "456"
    });
    

  • 我的 API 方法

  • My API methods

    [Authorize]
    public IEnumerable<string> Get()
    {
     return new string[] { "value1", "value2" };
    }
    

  • 推荐答案

    是使用 cookie 身份验证还是 (bearer) 令牌仍然取决于您拥有的应用程序类型.据我所知,目前还没有任何最佳实践.但由于您正在开发 SPA,并且已经在使用 JWT 库,因此我更喜欢基于令牌的方法.

    Whether to use cookie authentication or (bearer) tokens still depends on the type of app you have. And as far as I know there aren't any best practice yet. But since you are working on a SPA, and are already using a JWT library, I would favor the token based approach.

    不幸的是,我无法帮助您使用 ASP.NET,但通常 JWT 库会为您生成和验证令牌.您所要做的就是在凭据(和秘密)上调用 generateencodeverifydecode在随每个请求发送的令牌上.而且您不需要在服务器上存储任何状态,也不需要发送 cookie,您可能对 FormsAuthentication.SetAuthCookie(user.UserName, false) 做了什么.

    Unfortunately, I cannot help you with ASP.NET, but usually JWT libraries generate and verify the token for you. All you have to do is call generate or encode on the credentials (and the secret) and verify or decode on the token sent with every request. And you don't need to store any state on the server and don't need to send a cookie, what you probably did with FormsAuthentication.SetAuthCookie(user.UserName, false).

    我确定您的库提供了一个关于如何使用生成/编码和验证/解码令牌的示例.

    I'm sure your library provides an example on how to use generate/encode and verify/decode tokens.

    所以生成和验证不是你在客户端做的事情.

    So generating and verifying is not something you do on the client side.

    流程是这样的:

    1. 客户端将用户提供的登录凭据发送到服务器.
    2. 服务器验证凭据并使用生成的令牌进行响应.
    3. 客户端将令牌存储在某处(本地存储、cookie 或仅在内存中).
    4. 客户端将令牌作为授权标头发送到服务器的每个请求.
    5. 服务器验证令牌并相应地发送请求的资源或 401(或类似内容).

    第 1 步和第 3 步:

    app.controller('UserController', function ($http, $window, $location) {
        $scope.signin = function(user) {
        $http.post(uri + 'account/signin', user)
            .success(function (data) {
                // Stores the token until the user closes the browser window.
                $window.sessionStorage.setItem('token', data.token);
                $location.path('/');
            })
            .error(function () {
                $window.sessionStorage.removeItem('token');
                // TODO: Show something like "Username or password invalid."
            });
        };
    });
    

    只要用户打开页面,

    sessionStorage 就会保留数据.如果你想自己处理过期时间,你可以使用 localStorage 代替.界面是一样的.

    sessionStorage keeps the data as long as the user has the page open. In case you want to handle expiration times yourself, you could use localStorage instead. The interface is the same.

    第 4 步:

    要将每个请求的令牌发送到服务器,您可以使用 Angular 所称的 拦截器.您所要做的就是获取先前存储的令牌(如果有)并将其作为标头附加到所有传出请求中:

    To send the token on every request to the server, you can use what Angular calls an Interceptor. All you have to do is get the previously stored token (if any) and attach it as a header to all outgoing requests:

    app.factory('AuthInterceptor', function ($window, $q) {
        return {
            request: function(config) {
                config.headers = config.headers || {};
                if ($window.sessionStorage.getItem('token')) {
                    config.headers.Authorization = 'Bearer ' + $window.sessionStorage.getItem('token');
                }
                return config || $q.when(config);
            },
            response: function(response) {
                if (response.status === 401) {
                    // TODO: Redirect user to login page.
                }
                return response || $q.when(response);
            }
        };
    });
    
    // Register the previously created AuthInterceptor.
    app.config(function ($httpProvider) {
        $httpProvider.interceptors.push('AuthInterceptor');
    });
    

    并确保始终使用 SSL!

    这篇关于使用 webapi 进行 AngularJS 客户端路由和令牌身份验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆