I'm creating an AngularJS application that uses the JWT token for authentication. The token is being passed using the AngularJS interceptor as shown below.
'request': function(config)
{
if (store.get('jwt_token') != null)
{
config.headers['x-access-token'] = store.get('jwt_token');
}
else
{
config.headers['x-access-token'] = '';
}
return config;
}
Whenever I'm accessing any /restricted
pages, everything is working fine. The issue is when I'm going to the /restricted
page by directly typing the URL in the address bar (or refreshing the page), the AngularJS gets circumvented, and hence, the Interceptors don't intercept the request, and the token is not passed.
I've been searching for a while, I found some solutions like responding with a piece of code that loads the AngularJS then makes a redirect from there. However, I'm looking for a simpler/neater approach if possible as I might be missing something here.
I can detect if the request came from AngularJS or not by checking for the x-access-token
since I'm always passing it (empty value if user is not authenticated).
Solution
Alex's answer is pointing to the exact problem, thanks Alex.
I finally figured it out yesterday. The solution I went with was to make sure all the requests come from AngularJS, I have a list of the restricted pages, if any of them is requested, I'm calling a function to verify and validate the JWT token on server side, if it's valid, proceed, otherwise, go to login page. The key thing is to ensure that ALL requests should go to the index.html to make sure AngularJS is handling the routing.
This link helped me greatly to solve this issue.
http://arthur.gonigberg.com/2013/06/29/angularjs-role-based-auth/
It sounds as if there's a confusion between Angular's router and server endpoints.
You are presumably triggering the $http configuration while navigating through the application, using URL's tracked by Angular's router (which works fine), whereas the /restricted
URLs are server URLs.
Therefore, when you ask for anything /restricted
outside of the Angular app (in the browser), it is sending the request straight to the server, and not via the Angular router or application.
Basically, you need to create routes in your Angular app that are within the restricted
context, that when initialized, run the $http configuration. You should never be calling server end-points directly in the address bar, except for index.html
(/
).
I'd suggest having an Angular route called /restricted-area
so that when a user hits it, it will always use the $http methods you have, by being a dedicated Angular route, calling the server's /restricted
endpoint internally, via a controller.
I had asked the similar question 2 months ago. What I have understood is, normally before javascript frontend frameworks how the http request were served was:
But as the recent shift to various javascript frontend frameworks and use of RESTful api.s has begun, the request needs to have authorization header. Thus in many of the single page web apps with javascript frameworks like angularjs,
So when you make request from angular application. Your request is intercepted from angular application and intercepted by your interceptor. However when you enter the url from your address bar, the browser sends request directly to server, because at that point of the request, the browser has not loaded your angular web application.
What I suggest is you set html5mode to false and put a #
before your route.
like localhost/#/restricted
and do the routing from your route provider. When there is #
before your route, the request for /
goes to server, your application loads, and make some controller in /restricted
from your application make http request to desired server end point. In this way the request is sent through your application and will be intercepted by your interceptor. The refresh and directly typing the address in address bar works as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With