트러블슈팅

로컬스토리지에 token이 저장이 안되는 현상

cocodingding 2024. 1. 17. 02:45
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Login Form</title>
</head>
<body>

<!-- 로그인을 위한 폼 -->
<form id="loginForm" action="/login" method="post" enctype="multipart/form-data">
  <!-- email과 password를 form-data로 전송 -->
  <input type="text" name="email" placeholder="Email" required>
  <input type="password" name="password" placeholder="Password" required>
  <button type="submit">Login</button>
</form>

<script>
document.getElementById('loginForm').addEventListener('submit', function(event) {
  // 폼 제출을 막아 기본 동작을 중단
  event.preventDefault();

  // 로그인 요청 후 응답에서 Authorization과 Authorization-Refresh를 추출
  fetch('/login', {
    method: 'POST',
    body: new FormData(event.target),
  })
.then(response => {
  // 로그로 서버 응답 헤더 확인
  console.log('서버 응답 헤더:', response.headers.get('Authorization'));
  console.log('서버 응답 헤더:',  response.headers.get('Connection'));
  console.log('서버 응답 헤더:', response.headers.get('Authorization-Refresh'));

  // 로그인이 성공하면 Authorization과 Authorization-Refresh를 로컬 스토리지에 저장
  if (response.ok) {
    const authorizationHeader = response.headers.get('Authorization');
    const refreshHeader = response.headers.get('Authorization-Refresh');

    // 로그로 확인
    console.log('Authorization:', authorizationHeader);
    console.log('Authorization-Refresh:', refreshHeader);

    // 로컬 스토리지에 저장
    localStorage.setItem('Authorization', authorizationHeader);
    localStorage.setItem('Authorization-Refresh', refreshHeader);

    // 로그인 성공 후 원하는 페이지로 리다이렉트 (예: 레스토랑 페이지)
    window.location.href = 'http://localhost:8080/restaurants';
  } else {
    // 로그인이 실패한 경우에 대한 처리
    console.error('로그인 실패!');
  }
})
.catch(error => console.error('에러 발생:', error));
});
</script>

</body>
</html>
package com.challnege.delivery.global.jwt.handler;

import com.challnege.delivery.domain.member.repository.MemberRepository;
import com.challnege.delivery.global.jwt.jwt.JwtService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import java.io.IOException;

@RequiredArgsConstructor
public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private final JwtService jwtService;
    private final MemberRepository memberRepository;

    @Value("${spring.jwt.access.expiration}")
    private String accessTokenExpiration;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        String email = extractUsername(authentication);
        String accessToken = jwtService.createAccessToken(email);
        String refreshToken = jwtService.createRefreshToken();

        jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken);

        memberRepository.findByEmail(email)
                .ifPresent(user -> {
                    user.updateRefreshToken(refreshToken);
                    memberRepository.saveAndFlush(user);
                });

        // 로그인 성공 후 index.html로 리다이렉트
        super.setDefaultTargetUrl("http://localhost:8080/restaurants");
        super.onAuthenticationSuccess(request, response, authentication);
    }

    private String extractUsername(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        return userDetails.getUsername();
    }
}

 

 

서버에서 리다이렉트를 하기 위에

super.setDefaultTargetUrl("http://localhost:8080/restaurants");
super.onAuthenticationSuccess(request, response, authentication);

이 두 부분을 추가해주고 위의 html 파일에 보이는것처럼 토큰들을 로컬 스토리지에 저장하려고 했지만

토큰들이 저장되지 않았다.

그렇게 삽질을 계속 하는 와중에

클라이언트단에서도 리다이렉트가 가능한걸 알고 아무 생각없이 일단 리다이렉트 부분을 서버에서 지웠는데

귀신같이 저장이 됐다...

왜그런진 모르겠다

package com.challnege.delivery.global.jwt.handler;

import com.challnege.delivery.domain.member.repository.MemberRepository;
import com.challnege.delivery.global.jwt.jwt.JwtService;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import java.io.IOException;

@RequiredArgsConstructor
public class LoginSuccessHandler extends SimpleUrlAuthenticationSuccessHandler {

    private final JwtService jwtService;
    private final MemberRepository memberRepository;

    @Value("${spring.jwt.access.expiration}")
    private String accessTokenExpiration;


    @Override
    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        String email = extractUsername(authentication);
        String accessToken = jwtService.createAccessToken(email);
        String refreshToken = jwtService.createRefreshToken();

        jwtService.sendAccessAndRefreshToken(response, accessToken, refreshToken);

        memberRepository.findByEmail(email)
                .ifPresent(user -> {
                    user.updateRefreshToken(refreshToken);
                    memberRepository.saveAndFlush(user);
                });
    }

    private String extractUsername(Authentication authentication) {
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        return userDetails.getUsername();
    }
}