drewreed2005 / dre2.0

dre2.0
Apache License 2.0
0 stars 0 forks source link

Drew Reed, Period 1 - Debugging Event on Nighthawk Resources #7

Open drewreed2005 opened 7 months ago

drewreed2005 commented 7 months ago

This blog goes over the process of debugging our continued trimester 2-3 project, Nighthawk Coders. Specifically, this week, I've taken on the task of preparing the site for redeployment, which has included trying to get the /authenticate method to send a cookie to our frontend.

The State Prior to Debugging

Prior to debugging, we know that a cookie is not being sent to the frontend with an /authenticate request, but we do not know why or the details. We know that a cookie IS being send if the request is made from the backend's /login page, and we know that the same exact fetch method being used with our frontend, both deployed and undeployed, does NOT send a cookie. Hopefully, by debugging, we can discover why.

Debugging Setup

Frontend

I started by running the frontend locally using the make command so that I can make quick modifications and have the site rebuild dynamically as new changes are saved.

Screen Shot 2024-03-07 at 12 10 17 PM

I set breakpoints on the initial fetch (for backend debugging when applicable) and the error/success messages following it so that I can capture the error as it occurs.

Backend

I started by running the backend from the debug option in Main.java.

Screen Shot 2024-03-07 at 12 13 37 PM

I set breakpoints at parts of the authenticate method that would show the cookie being actively created. This would allow me to see if there was a problem generating the cookie when it's sent from the frontend, or if the problem was something to do with the way the frontend handled the request.

Screen Shot 2024-03-07 at 12 14 30 PM

Generating Errors

To demonstrate understanding, I wanted to show off the process of generating the errors shown in the class demonstration on Tuesday, but within the framework of our group's project.

Connection Refused Error

I stopped the backend just once to demonstrate a connection refused error, which indicates that the backend isn't up in the first place or that the request being made isn't able to access the backend somehow.

Screen Shot 2024-03-07 at 12 18 21 PM

I stepped through the process until it showed the failure.

CORS Error

To demonstrate a CORS error, I removed the localhost from the AllowedOrigins section of MvcConfig.java:

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("https://john-scc.github.io"); // COMMENTED OUT, "http://localhost:4100", "http://127.0.0.1:4100");
    }

Now, if any request is made, a preflight error will be triggered, as access cannot be granted to the frontend:

Screen Shot 2024-03-07 at 12 40 19 PM

401 Error

The 401 error is one that has been experienced before with this project. I was able to trigger this by modifying the permitAll() line in the SecurityConfig. Before:

// list the requests/endpoints need to be authenticated
.authorizeHttpRequests(auth -> auth
    .requestMatchers(HttpMethod.POST,"/authenticate").permitAll()

And then after:

// list the requests/endpoints need to be authenticated
.authorizeHttpRequests(auth -> auth
    .requestMatchers(HttpMethod.POST,"/authenticate").hasAnyAuthority("ROLE_ADMIN")

Someone who isn't already logged-in as an admin will get this result when trying to log in here:

Screen Shot 2024-03-07 at 12 47 34 PM

Debugging for Cookie Generation

Here is where I focused on some really useful debugging that may help determine why a cookie is not being generated on the frontend when an /authenticate request is made.

I input a valid email and password and began to step through on the backend (see below):

Screen Shot 2024-03-07 at 12 58 26 PM Screen Shot 2024-03-07 at 1 05 32 PM

In the screenshot above, you can see that the necessary information, including email, password, roles and encrypted token is being recognized properly.

Screen Shot 2024-03-07 at 1 07 54 PM

The data appears to remain properly stored and utilized up until the return is called.

Screen Shot 2024-03-07 at 1 10 37 PM

The data was logged, but the cookie still remains absent even after redirect and reload.

Data Captured in Debugging

I didn't do this with a GET request because it simply wouldn't help us get to the results we wanted! We wanted to use debugging for good and so we did! Here's a screenshot:

Screen Shot 2024-03-07 at 7 15 55 PM

In red: this is the request object sent to the /authenticate request for sign-in. You can see its two attributes here. These are accessed to view user data.

In yellow: this is a List of user roles, which only has one role in this case. Its name attribute, "ROLE_USER," which is the one role that Toby has in the database, is displayed here. We can see that his data was successfully accessed. (Though this can also be seen in the yellow text on the right of the prior images, which recognized his user. It also wouldn't continue if the user wasn't found (null) earlier in the process. By seeing this, though, we know that the proper data is being put in the cookie.)

In green: this is just a String, but it's VERY important in this debugging the token because that is the most important set of contents stored within the JWT that will be used for future user verification.

Results

Although this doesn't show exactly what the problem is, it does confirm that the request is being fully made and processed. This leads me to believe that it has something to do with the settings of the cookie or the header "HttpHeaders.SET_COOKIE".

Problem Solved!

I figured out that the issue must've been frontend-related (obviously), especially since the request made on the backend works.

I determined that the difference between the mechanics of making the request same-site versus using CORS could have been the issue, and this made me wonder if there request options were part of the problem. After reimplementing the old cookie mechanics (which I go more into in my individual ticket), I tried this new set of request settings based on the teacher_portfolio's request:

  var requestOptions = {
      method: 'POST',
      mode: 'cors', // no-cors, *cors, same-origin
      cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
      credentials: 'include', // include, *same-origin, omit
      body: JSON.stringify(requestBody),
      headers: {
          "content-type": "application/json",
      },
  };

It seems that including credentials and specifying that the mode is 'cors' was enough to make this magic happen:

Screen Shot 2024-03-07 at 2 29 48 PM

Finally, it seems that we're ready to deploy our backend with full functionality!

KKcbal commented 7 months ago

You get a 2.0/2.0

You had everything done and explained it all to me in person. There was a valuable debugging experience that resulted in fixing the JWT. You showed multiple other errors and showed data captured by the backend. Good job. Very thorough. :3