Solution of the Cors Error From a Spring Boot and Angular Application

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
I faced the CORS error every time I create a  new project. But this problem only occurs in   some particular cases. the CORS error means Cross  Origin Resources Sharing error. But this error   only happens in the browsers. If I request  my backend from a terminal or from Postman,   I won't see the error. It only happens in browsers  because they have some security conditions. If the   frontend tries to access a backend which doesn't  have the same URL, the browser throws an error.   Cross Origin Resources Sharing means that the  frontend and the backend are at different URLs,   at different Origins. And there is no information  about letting them share resources. Because what   if a hacker copy a website and use the same  backend? The frontend will be a different URL,   but the website will consume the same backend.  When I try to access my personal account,   I won't notice anything strange, as the data is  all good. Meanwhile, the website will steal my   personal account. This is why the backend must  identify the trusted frontends. To solve this,   there are some HTTP headers which tell the  browser that the frontend and the backend   work together. Those headers are Access Control  Allow Origin, Access Control Request Method,   Access Control Request Headers. Those are headers  sent by my backend to tell the browser how to   protect the user. The first header tells the  browser which frontend can request the backend.   But this one alone is not enough. The second  header tells the browser which HTTP method is   accepted by the backend. And the last header tells  which headers are accepted by my backend. In fact,   the browser will perform a first request to  check if the backend is okay with the current   frontend. This is called the pre-flight request.  And it's done with the Options HTTP method. The   pre-flight request is a request done automatically  by the browser. This is why I don't see it from a   terminal or from Postman. So, the CORS error  can only be solved by configuring my backend   to accept a frontend with a different origin.  Let's see how. Let's start by creating a new   Spring Boot project. Because, as said,  this always happens with new projects.   I set the package. I choose Maven. I set  the artifact name, and the project name.   I will only add the web dependency. Because the  problem is visible in the most simple Spring Boot   application. Let's download it and open it with  IntelliJ. I will start by creating a controller.   Let's create the controllers package,  and my controller, greetings. It will be a rest controller.  With a get endpoint, greetings. And return a DTO. Let's create the DTO as a record in the DTOs  package. And it only contains one field. And now return the content. "hello" Let's start my application and test this endpoint. curl localhost 8080 greetings. I can request  the endpoint without any problem. I got the   response. Everything is okay. I can even  test it from Postman. localhost 8080   and send. Everything is okay  too. As a backend developer,   I won't go any further. I've tested my application  from a terminal and from Postman. And everything   goes fine. So it's time to push to production.  But what happens when the frontend access this   endpoint? Let's create an Angular project. NG new  frontend. Let's pick the default rooting and CSS. I won't create any new component.  Just a simple paragraph in the   main component and request the backend. Let's first remove all the HTML content. Add  a title, message received from the backend. And in the paragraph, I will put a variable  that I will create in my component. In the Typescript component, let's  first import the HTTP client. The response variable. In the  constructor, inject the HTTP client. And now, in the initialization of the  component, I will request the backend. Get, BackendContent, I will  create this interface later.   The endpoint now, localhost 8080  greetings, and subscribe to the response. I will save in the variable  the response from my backend. Let's now create the backend content. It's just an interface. With the field content. Let's import the backend content. And import the HTTP module. Ok, I have my Angular   application which requests my backend, and simply  displays the response. Let's test both together.   Let's first go into the frontend folder,   NG serve to start my frontend. And  now in the browser, I see the empty. Here I can see that the greetings endpoint  responds with an error. If I look carefully   I see that the request wasn't even sent. It's a  pre-flight request. The same happens with other   browsers. But at the beginning I've said  that this only happens when the frontend   and the backend are at different Origins.  Let's see what happens when both are at the   same origin. Both the frontend and the backend  at the same origin means that both are served   by the same web server. So I must include the  frontend inside my backend. But I can't do this   with Angular. So I will just create a simple  HTML page with an Ajax request to my backend.   Let's first go to the resources folder. Into  the static I will create the index.html. I create a title and a paragraph. Now at the beginning, I will insert the  JavaScript. I will add an event listener. to know when the content is loaded. When loaded, I will execute this function. Instantiate xhr, which allows  me to perform Ajax requests. Response type is the Json. And when loaded, I will call this function. If the request is done correctly, I will replace the paragraph content with the content of the response. Let's open the Ajax request with a get to  the greetings endpoint. And make the call.   Now create an endpoint to deserve this content. Let's create another controller. Now this time is  not a rest controller but just a plain controller.   It will return a string which is just the  path of the index HTML file. Let's test this. With this configuration, everything goes fine.  Because the frontend is at the localhost 8080   and the backend is at localhost 8080. But as  said, I can't do that with Angular. I have   to configure my backend to accept a frontend  from a different origin. Let's see a quick fix. Let's add the CrossOrigin annotation. And with the  origins, http localhost 4200. Let's test again. Now it works. But I have to include the  CrossOrigin annotation at all the endpoints.   This is not suitable. So I have to create a  global configuration. Let's first comment this   annotation. And now create another package,  config. I will put the configuration in a   class named WebConfig. Add the configuration  annotation. And the bean, WebMVCConfigurer. I will just implement the add CORS method. Registry, add the mapping to all the routes. Allow the origin of the frontend URL. Add some accepted methods. get post and delete. And now add some accepted headers. content type and authorization. Notice that this  method accepts a list of strings,   a list of URLs. This means that  I can put all the frontends,   from all the environments of my application,  and the localhost address too. Let's test again. It still works. And it will work for any new  endpoint I create in my backend. This is a   typical error, and it has a simple solution on  the backend side. I hope you find this video   useful. Before leaving click on the like button,  subscribe to my channel and see you soon. Bye!
Info
Channel: The Dev World - by Sergio Lema
Views: 5,576
Rating: undefined out of 5
Keywords: java, spring boot, angular, cors error, spring security, Resolution of the Cors Error From a Spring Boot and Angular Application
Id: uMJnAxapF7E
Channel Id: undefined
Length: 12min 5sec (725 seconds)
Published: Mon Aug 28 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.