2014-01-21 2 views
31

asp.net mvc webapi를 백엔드 및 클라이언트 측 라우팅 (cshtml 없음)으로 사용하는 SPA angularjs 응용 프로그램에서 인증 및 권한 부여 용 예제를 만들고 싶습니다. 다음은 완전한 예제를 설정하는 데 사용할 수있는 함수의 예입니다. 그러나 나는 그걸 모두 togehter에 넣을 수 없다. 어떤 도움을 주셔서 감사합니다.webapi를 통한 AngularJS 클라이언트 측 라우팅 및 토큰 인증

질문 :

  1. 가장 좋은 방법은 무엇입니다 : 쿠키 또는 토큰 기반?
  2. 각 요청마다 인증을 위해 무기 토큰을 생성하려면 어떻게해야합니까?
  3. API 함수에 대한 유효성 확인?
  4. 클라이언트에서 서명 된 인증을 어떻게 보존합니까?

예제 코드 :

<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> 
  • 인증 각도 컨트롤러

    $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 코드 형태로

    1. 로그인. 컨텐츠를 제한하기위한 JWT 라이브러리를 사용

      [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); 
      } 
      
    2. 인증 .

      config.MessageHandlers.Add(new JsonWebTokenValidationHandler 
      { 
          Audience = "123", 
          SymmetricKey = "456" 
      }); 
      
    3. 내 API 방법

      [Authorize] 
      public IEnumerable<string> Get() 
      { 
      return new string[] { "value1", "value2" }; 
      } 
      
      쿠키 인증 또는 (무기명)를 사용할지 여부
  • 답변

    89

    는 여전히 토큰 당신이 응용 프로그램의 유형에 따라 달라집니다. 그리고 제가 아는 한 아직까지 최선의 방법이 없습니다. 그러나 SPA에서 작업 중이며 이미 JWT 라이브러리를 사용하고 있으므로 토큰 기반 방식을 선호합니다.

    불행히도 저는 ASP.NET에 관해 당신을 도울 수는 없지만, 보통 JWT 라이브러리는 당신을 위해 토큰을 생성하고 확인합니다. 자격 증명 (및 비밀 번호)에 generate 또는 encode으로 전화하고 모든 요청과 함께 토큰에 verify 또는 decode을 보내면됩니다. 그리고 서버에 상태를 저장할 필요가 없으며 FormsAuthentication.SetAuthCookie(user.UserName, false)과 같이 쿠키를 보낼 필요가 없습니다.

    라이브러리에 생성/인코딩 및 확인/디코딩 토큰을 사용하는 방법에 대한 예제가 나와 있습니다.

    그래서 생성 및 확인은 클라이언트 측에서하는 작업이 아닙니다.

    흐름은 이런 식입니다 :

    1. 클라이언트는 서버에 사용자가 제공 한 로그인 자격 증명을 보냅니다.
    2. 서버는 자격 증명을 인증하고 생성 된 토큰으로 응답합니다.
    3. 클라이언트는 토큰을 어딘가에 저장합니다 (로컬 저장소, 쿠키 또는 메모리에 저장).
    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을 대신 사용할 수 있습니다. 인터페이스는 동일합니다.

    4 단계 :

    서버에 대한 모든 요청에 ​​토큰을 보내려면, 당신은 각도가 Interceptor을 부르는 사용할 수 있습니다.

    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을 사용해야합니다 : 당신이해야 할 모든 이전에 저장된 토큰을 얻을 수 (있는 경우) 모든 나가는 요청에 헤더로 첨부입니다!

    +0

    정말 대단한 설명입니다. 제가 찾고 있었던 것입니다. 답변과 자세한 예제를 보내 주셔서 감사합니다. –

    +0

    물론 도움이 되었으면 좋겠다. – bernhardw

    +0

    숨겨진 i- 프레임 (인증 서버가 이전 사용 권한을 기억하고 있다고 가정)에 의해 액세스 토큰을 새로 고치는 방법이 있습니까? – g18c

    관련 문제