3

I have a web app built by AngularJs and a backend app built by Spring and I'm using JWT to secure my app. With Get method everything is ok, at the backend level I get the bearer token I'm expecting so I can return private information. But with POST method the bearer token is not sent. I don't know if this is an issue from backend or frontend layer. here you have my code:

AngularJS

$http({
        method: 'POST',
        url: SessionService.apiUrl + '/category/create',
        headers: {
          'Accept': 'application/json','Content-Type': 'application/json; 
           charset=UTF-8;', 'Authorization': 'Bearer ' + SessionService.getToken()
       },
        data: params
 })

For GET method I have exactly the same (without params and with method GET) and it is working.

At Backend:

@RequestMapping(value = "/category/create", method = RequestMethod.POST)
    public @ResponseBody
    Response add(@RequestBody CategoryBO request) {
...
}

And to get the Authorization header I'm using io.jsonwebtoken library in the following way:

protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        String authorizationHeader = request.getHeader("authorization");

Using Postman the backend is working well, but with angularjs is not.

GET - Request Header:

Accept:application/json, text/plain, */*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6,pt;q=0.4
Authorization:Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJmYWJpYW4uYW5nZWxvbmkiLCJyb2xlcyI6IkFETUlOIiwiaWF0IjoxNDU5MDE5MTg0fQ.QAPZDbyavambfdK9LJUQWyzSRAuELvg_IGTjFdsm6cc
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36

POST - Resquest Header

Accept:*/*
Accept-Encoding:gzip, deflate, sdch
Accept-Language:es-ES,es;q=0.8,en;q=0.6,pt;q=0.4
Access-Control-Request-Headers:accept, authorization, content-type
Access-Control-Request-Method:POST
Connection:keep-alive
Host:localhost:8080
Origin:http://localhost:3000
Referer:http://localhost:3000/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Faabass
  • 1,394
  • 8
  • 29
  • 58
  • Inspect actual request in browser dev tools network as well as check console for errors. I suspect you have a CORS problem and need to make sure it is implemented on server api endpoint – charlietfl Mar 26 '16 at 19:36
  • 1
    In my spring controller I have "@CrossOrigin(origins = "http://localhost:3000")" and when I debug I can see that the JWT method is called and there I can see that the Authorization header is coming as NULL in POST method and with the correct value in GET. Is there any particular thing I need to do? – Faabass Mar 26 '16 at 19:45
  • Doesn't clarify what is actually sent in the request as mentioned above. Or if you are handling OPTIONS preflight requests and headers are set on them, or if you are getting CORS errors Your browser is debug tool of choice to start with – charlietfl Mar 26 '16 at 19:49
  • @charlietfl I added the Request header to the comment, there you can see how they change based on if it is a GET or a POST. I guess that both should ne the same, maybe that is the issue... And I think that if I can debug on the server is because it is not a CORS issue and also it shoud be the same for GET and POST request, right? – Faabass Mar 26 '16 at 20:28
  • might try setting `withCredentials` ..see docs. Not sure how request headers are getting any `Access-Control` set...those are response headers typically – charlietfl Mar 26 '16 at 20:34

2 Answers2

0

I had a similar issue and then i realized that the frontend trigger a preflight request before the actual doing a HTTP.OPTIONS request. More info here

Such request will not have the Authorization token and hence the access to the controller will fail.The most natural solution so, will be to set the security of your application by letting pass all the OPTIONS requests.

This can be done

Hope it helps

Community
  • 1
  • 1
FrancescoM
  • 1,400
  • 11
  • 16
0

Thanks @user2858970 for the explanation. I found it very lucid.

To get the issue resolved, you basically need to work with two stuff:

  1. Enable CORS in your server because your server has to know that it is getting request from client which is in different domain.
  2. Enable CORS at Spring Security level as well to allow it to leverage the configuration defined at Spring MVC level.

I've put the explanation along with code to answer CORS with spring-boot and angularjs not working .

Yogen Rai
  • 2,961
  • 3
  • 25
  • 37