Interceptors: http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/
Explanation with example project: http://www.codeproject.com/Articles/784106/AngularJS-Token-Authentication-using-ASP-NET-Web-A
Another good artcle about WebAPI and AngularJS: http://bitoftech.net/2013/12/03/enforce-https-asp-net-web-api-basic-authentication/
On WebAPI side you must add [RoutePrefix("api/Orders")] before ApiControler declaration and
[Authorize][Route("")] before function declaration, also you sould add code for check authentication:
ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
var userName = principal.Claims.Where(c => c.Type == "sub").Single().Value;
namespace AngularJSAuthentication.API.Controllers
{
[RoutePrefix("api/Orders")]
public class OrdersController : ApiController
{
[Authorize]
[Route("")]
public IHttpActionResult Get()
{
ClaimsPrincipal principal = Request.GetRequestContext().Principal as ClaimsPrincipal;
var userName = principal.Claims.Where(c => c.Type == "sub").Single().Value;
return Ok(Order.CreateOrders());
}
}
}
Interceptor is regular service (factory) which allow us to capture every XHR request and manipulate it before sending it to the back-end API or after receiving the response from the API. In our case, we are interested to capture each request before sending it so we can set the bearer token, as well we are interested in checking if the response from back-end API contains errors which means we need to check the error code returned so if its 401 then we redirect the user to the log-in page.
To do so, add new file named “authInterceptorService.js” under “services” folder and paste the code below:
'use strict';
app.factory('authInterceptorService', ['$q', '$location',
'localStorageService', function ($q, $location, localStorageService) {
var authInterceptorServiceFactory = {};
var _request = function (config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
var _responseError = function (rejection) {
if (rejection.status === 401) {
$location.path('/login');
}
return $q.reject(rejection);
}
authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
return authInterceptorServiceFactory;
}]);
By looking at the code above, the method “
_request” will be fired before $http sends the request to the back-end API, so this is the right place to read the token from local storage and set it into “Authorization” header with each request. Note that I’m checking if the local storage object is nothing so in this case this means the user is anonymous and there is no need to set the token with each XHR request.
Now the method “
_responseError” will be hit after we receive a response from the back-end API and only if there is failure status returned. So we need to check the status code, in case it was 401 we’ll redirect the user to the log-in page where he’ll be able to authenticate again.
Now we need to push this inspector to the inspectors array, so open file "app.js" and add the below code snippet:
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptorService');
});
By doing this, there is no need to setup extra code for setting up tokens or checking the status code, any AngularJS service executes XHR requests will use this interceptor. Note: This will work if you are using AngularJS service
$httpor $resource.
No comments:
Post a Comment