Bulls 프로젝트 3

chaean·2023년 9월 8일

프로젝트 - Bulls

목록 보기
3/11

Cookie, Local Storage, Session Storage중 하나에 저장하여
"로그인을 유지"하는 것이 아니였다.
프론트에서 담을 공간을 정하는 방식.

난 그 중 Cookie를 사용해보기로 했다.

1. JWT발급(Backend)

2. 쿠키에 저장(Frontend)

3. 권한이 필요할 때 쿠키에서 JWT를 가져와 헤더에 추가하여 API와 통신

이러한 방식으로 진행된다.

Frontend에서 Cookie를 사용하기 위해 react-cookie 라이브러리를 사용하였다.

설치 npm install react-cookie

- Cookie를 관리하기 위한 CookieUtil 생성

import {Cookies} from "react-cookie";

const cookies = new Cookies();

export const setCookie = (name, value, options) => {
    return cookies.set(name, value, {...options});
}

export const getCookie = (name) => {
    return cookies.get(name);
}

export const removeCookie = (name) => {
    return cookies.remove(name);
}

- 권한이 필요한 URL에 접근하기 위해 헤더에 JWT를 추가

import {useEffect, useState} from "react";
import {getCookie} from "./CookieUtil";

function UserList() {
    const [users, setUsers] = useState([]);

    useEffect(() => {
        fetch('/users', {
            method: "GET",
            headers: {
                "Authorization": "Bearer " + getCookie("JWT")
            }
        })
            .then(response => response.json())
            .then(data => setUsers(data))
            .catch(err => console.error("Error = ", err));
    }, []);

    return (
      <div>
          <table>
              <thead>
              <tr>
                  <th>id</th>
                  <th>student_id</th>
                  <th>password</th>
                  <th>email</th>
                  <th>name</th>
                  <th>sex</th>
                  <th>phone</th>
              </tr>
              </thead>
              <tbody>
              {users.map(user => (
                  <tr key={user.id}>
                      <td>{user.student_id}</td>
                      <td>{user.password}</td>
                      <td>{user.email}</td>
                      <td>{user.name}</td>
                      <td>{user.sex}</td>
                      <td>{user.phone}</td>
                  </tr>
              ))}
              </tbody>
          </table>
      </div>
    );
}

export default UserList;

- 이에 따라 Controller에서 Header 및 Cookie를 추가해줄 필요가 없으므로 코드 수정

@PostMapping("/loginForm")
public ResponseEntity<LoginResponseDTO> loginPost(@RequestBody @Valid LoginRequestDTO loginRequestDTO) {

    String token = userService.login(loginRequestDTO.getStudent_id(), loginRequestDTO.getPassword());

    if (token != null){
        log.info("로그인 POST  1 [성공]");

        return new ResponseEntity<>(new LoginResponseDTO(token), HttpStatus.OK);
    }
    else {
        log.info("로그인 POST  2 [실패]");
        // 401에러
        return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(new LoginResponseDTO("애프리케이션 ID 또는 암호에 오류가 있습니다."));
    }
}

CORS (Cross-Origin-Resource-Sharing)

교차 출처 리소스 공유를 뜻하는 CORS는, '서로 다른 출처에서 리소스를 공유하는 것'을 뜻한다.

fetch('http://localhost:8080/users’) -> cors오류 발생하는데
fetch(‘/users’) -> cors오류가 발생하지않음

왜? why?

  1. 동일 출처 정책 (Same-Origin Policy):
    웹 브라우저는 보안상의 이유로 기본적으로 다른 출처 (Origin)의 리소스에 대한 접근을 제한합니다. 출처란 프로토콜 (HTTP, HTTPS), 호스트 (도메인), 포트로 구성됩니다. 따라서 두 개의 URL이 동일한 출처를 갖는다면 CORS 오류가 발생하지 않을 것입니다.

  2. fetch('/users')는 현재 웹 페이지의 동일한 출처에 있는 리소스를 가져오려고 시도하므로 CORS 오류가 발생하지 않을 것입니다.
    다른 출처에서 리소스 요청:
    만약 fetch 함수를 사용하여 다른 출처의 리소스 (예: 다른 도메인, 다른 포트)에 접근하려고 한다면, 웹 브라우저는 이를 보안상의 이유로 차단합니다. 이것이 바로 CORS 정책입니다. 따라서 fetch('http://localhost:8080/users')와 같이 다른 도메인 또는 포트로 요청을 보내면, 브라우저는 보안 정책을 위반했다고 판단하고 CORS 오류를 발생시킵니다.

from chatGPT...

CORS문제를 해결하기 위해서는 spring security에 설정을 해줘야 한다.

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
            .allowedOrigins("http://localhost:3000") // React 앱의 도메인 주소
            .allowedMethods("GET", "POST", "PUT", "DELETE")
            .allowedHeaders("*")
            .allowCredentials(true);
}

'
'
'
'
'
처음 Spring과 React를 연결할 때 찾아보다 보니 알게된 것들!

  • Route - 사용자가 요청한 URL에 따라 해당 URL에 맞는 페이지를 보여주는 것이라고 생각할 수 있다.
  • Link와 a href의 차이 - 결과적으로는 a href로 페이지를 이동하면 상태 값을 잃고 속도가 저하된다.
    Link컴포넌트는 HTML5 History API를 사용하여 브라우저의 주소만 바꿀 뿐, 페이지를 새로 불러오지는 않기때문!
    따라서 React에서는 Link 컴포넌트 사용을 권장한다

'
'
'

개강 이슈로 속도가 느려졌지만 앞으로 JWT를 refresh Token과 access Token으로 나누어 보는 작업을 해보려고 한다.👍

profile
백엔드 개발자

0개의 댓글