How to conditionally bypass request interceptor in AngularJs - angularjs

I'm having trouble bypassing my auth interceptor:
request: function (config) {
if (config.headers["NoAuth2"] !== null) return config;
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
config.headers.Authorization = 'Bearer ' + authData.token;
} else {
var authService = $injector.get('authService');
authService.logOut();
$location.path('/login');
}
return config;
}
Ideally, when the headers have NoAuth2 present in it's collection, I'd like to bypass adding the token and just return the config via something like:
$http.post(config.url + "pubrequest", request, { headers : {NoAuth2 : 1}})
From my controller.
However, I can't seem to get it to work despite several SOE examples on it, any ideas?

Related

How to override header Token with AngularJS

I have problem to override header token with AngularJS becauase already set with AuthInterceptor.
app.factory('authInterceptor', function ($rootScope, $q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if (localStorage.getItem("token")!=='') {
config.headers.Authorization = 'Bearer ' + localStorage.getItem("token");
}
return config;
},
};
});
app.config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});
I would access another third party URL where using another Token,but always failed, because Token back to current Token in localStorage. I have used TransformRequest, but not work too, what is best practice to solve the problem?
You could check that the URL in the intercepted request is a URL that you want to pass an authorization token. For instance, if the URL to your own API always starts with https://api.myapp.com, you could do it like this:
app.factory('authInterceptor', function ($rootScope, $q, $window) {
var urlForAuthorization = 'https://api.myapp.com';
return {
request: function (config) {
config.headers = config.headers || {};
if (config.url.startsWith(urlForAuthorization)
&& localStorage.getItem("token") !== '') {
config.headers.Authorization = 'Bearer ' + localStorage.getItem("token");
}
return config;
}
};
});

Add an exception do defaults headers in angularJS

Hello I want to use external API to gather all the current currency rate. My front is based on token and I am storing token in localForage which is nothing but async localStorage.
//this execute after every page refresh
$localForage.getItem('authorization')
.then(function(authData) {
if(authData) {
$scope.authentication.isAuth = true;
$http.defaults.headers.common.Authorization = 'Bearer ' + authData.token;
//set authentication variable to true and add token to every request after page refresh
}
}, function(){
console.log("error with getting authorization localForage after refresh");
}
);
//this execute after custom event emitted after success login response
$rootScope.$on('localForageUpdated', function(event){
$localForage.getItem('authorization')
.then(function(authData) {
if(authData) {
$http.defaults.headers.common.Authorization = 'Bearer ' + authData.token;
$scope.authentication.isAuth = true;
//set authentication variable to true and add token to every request after page refresh
} else {
$scope.authentication.isAuth = false;
}
}, function(){
console.log("error with getting authorization localForage on event");
}
);
});
So this basically add header with token before every backend request.
Unfortunately when I try to download all the current currency rate from external API I get following error:
Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
That's due to fact I added header with my token. Can I somehow add an exception while seting $http.defaults.headers.common.Authorization = 'Bearer ' + authData.token;?
Here is my solution you can use it to inspire you.
I create au interceptor to add the authorization. In this interception you can put your exception logic base on your need in my case I base it on the url.
angular.module('yourAppName').factory('authInterceptor', function ($q, $window) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($window.localStorage.token
&& $window.localStorage.token !== undefined
&& $window.localStorage.token !== 'undefined') {
if(config.url.startsWith("xyz")){
delete config.headers.Authorization;
} else {
config.headers.Authorization = 'Bearer ' + $window.localStorage.token;
}
}
return config;
},
response: function (response) {
return response || $q.when(response);
},
// optional method
responseError: function (response) {
return $q.reject(response);
}
};
});
angular.module('rmsApp').config(function ($httpProvider) {
$httpProvider.interceptors.push('authInterceptor');
});

angular auth interceptor on selected request

I have written an auth interceptor that adds auth token to the request and handles auth errors if the user is not logged in.
var storeApp = angular.module('storeApp');
storeApp.factory('authInterceptor', function ($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) {
return response || $q.when(response);
},
responseError: function (response) {
if (response.status === 401 || response.data.error === 'token_not_provided') {
console.log('auth error');
}
return $q.reject(response);
}
};
});
storeApp.config(function ($httpProvider) {
$httpProvider.defaults.withCredentials = true;
$httpProvider.interceptors.push('authInterceptor');
});
The issue is the auth interceptor is added to every request, regardless the request requires authentication or not. What is the best way to create an auth interceptor that only intercepts when the route requires authentication?
You need the filter out the requests you want in the authInterceptor factory methods
['/whatever/1', '/whatever/2', '/whatever/3'].forEach(function(value){
if (response.config.url.startsWith(value)) {
// do something
}
})
return response;

How to skip angularjs interceptor for an HTTP request?

I have an angularjs app, in which I have an interceptor that adds the authorization token to the header of each request.
However, somewhere in the application I need to use and external API where the interceptor ruins it, because it adds this authorization header which is not acceptable by this external API provider. How can I make angularjs HTTP skip the interceptor, only on this one specific case?
The interceptor code is below:
app.factory('authInterceptorService', ['$q', '$injector', '$location', 'localStorageService', function ($q, $injector, $location, localStorageService) {
var authInterceptorServiceFactory = {};
var $http;
var _request = function (config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
//console.log("token: " + authData.token.substring(0, 10));
//console.log("user: " + authData.userName);
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
var _responseError = function (rejection) {
var deferred = $q.defer();
if (rejection.status === 401) {
var authService = $injector.get('authService');
authService.refreshToken().then(function (response) {
_retryHttpRequest(rejection.config, deferred);
}, function () {
authService.logOut();
$location.path('/login');
deferred.reject(rejection);
});
} else {
deferred.reject(rejection);
}
return deferred.promise;
}
var _retryHttpRequest = function (config, deferred) {
console.log('retrying');
$http = $http || $injector.get('$http');
$http(config).then(function (response) {
deferred.resolve(response);
//console.log("success:" +response);
}, function (response) {
deferred.reject(response);
//console.log("error:" + response);
});
}
authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
return authInterceptorServiceFactory;
}]);
Easy
$http.get("url" , {noAuth : true}).then(success(),error());
In the Interceptor
var _request = function (config) {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData && !config.noAuth) {
//console.log("token: " + authData.token.substring(0, 10));
//console.log("user: " + authData.userName);
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
Simple. Change this line
if (authData) {
to
if (authData && !config.headers.hasOwnProperty('Authorization')) {
And for any request where you do not want the header applied, use
$http({
headers { Authorization: null },
// and the rest
})
Write like this :-
var _request = function (config) {
if (config.url.indexOf('yourExternalApiUrl') > -1) {
return config;
} else {
config.headers = config.headers || {};
var authData = localStorageService.get('authorizationData');
if (authData) {
//console.log("token: " + authData.token.substring(0, 10));
//console.log("user: " + authData.userName);
config.headers.Authorization = 'Bearer ' + authData.token;
}
return config;
}
}
For more details you can see : http://www.codemosquitoes.com/2016/06/using-angularjs-interceptors-with-http.html
If you are looking for the auth0 interceptor:
export class InterceptorService implements HttpInterceptor {
constructor(private auth: AuthService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
var allow = ['/assets/i18n/de.json', '/assets/i18n/en.json'];
if (allow.includes(req.url)) {
const noToken = req.clone();
return next.handle(noToken);
}
return this.auth.getTokenSilently$().pipe(
mergeMap(token => {
const tokenReq = req.clone({
setHeaders: { Authorization: `Bearer ${token}` }
});
return next.handle(tokenReq);
}),
catchError(err => throwError(err))
);
}
}

TypeScript interceptor in AngularJS

I'm having problems setting up a request interceptor in AngularJS using TypeScript
The following snippet works, not working variant is commented out. No matter what I inject in the constructor the local variables are undefined in the request method.
module Services
{
export class AuthInterceptor
{
public static Factory(TokenService: Services.ITokenService)
{
return new AuthInterceptor(TokenService);
}
constructor(private TokenService: Services.ITokenService)
{
this.request = (config: ng.IRequestConfig) =>
{
config.headers = config.headers || {};
if(this.TokenService.IsAuthorised())
config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
return config;
};
}
public request: (config: ng.IRequestConfig)=>ng.IRequestConfig;
/* THIS IS NOT WORKING
public request(config)
{
// this.TokenService is undefined here as well as $window or $q which I tried to inject
config.headers = config.headers || {};
if(this.TokenService.Token != "")
config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
return config;
}
*/
}
}
angular.module("Services")
.config(($httpProvider: ng.IHttpProvider)=>
{
$httpProvider.interceptors.push(Services.AuthInterceptor.Factory);
});
It is because of the wrong this. Solution:
public request = (config) =>
{
// this.TokenService is undefined here as well as $window or $q which I tried to inject
config.headers = config.headers || {};
if(this.TokenService.Token != "")
config.headers.Authorization = 'Bearer ' + this.TokenService.Token;
return config;
}
To understand why you need this : https://www.youtube.com/watch?v=tvocUcbCupA&hd=1

Resources