프로젝트

트러블슈팅 프론트앤드 백앤드 cors 에러 login 토큰 에러

늘곰's 2023. 10. 12. 18:02

'http://localhost:5173'에서 
'http://54.180.91.54:3000/users/signup'로 요청을 보내려고 할 때
 CORS 정책 때문에 차단되었다고 나와 있어.




Access to XMLHttpRequest at 'http://54.180.91.54:3000/users/signup' from origin 
'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

 // CORS 설정
  app.enableCors({
    origin: 'http://localhost:5173',
    //origin: ['http://localhost:5173', 'http://localhost:3000'],
    //origin: '*', // 클라이언트 애플리케이션의 주소로 변경 개발단계라서 *로 한것 배포시 수정해야함/ 허용할 도메인 주소 확인
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    credentials: true, // 쿠키를 사용하려면 true로 설정
    exposedHeaders: ['accessToken', 'refreshToken'],
  });
  
  
  이 에러는 origin 에서 와일드 카드를 사용해서 에러가 뜸,



join:1 Access to XMLHttpRequest at 'http://54.180.91.54:3000/users/signup' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

  // CORS 설정
  app.enableCors({
    origin: 'http://localhost:5173',
    //origin: ['http://localhost:5173', 'http://localhost:3000'],
    //origin: '*', // 클라이언트 애플리케이션의 주소로 변경 개발단계라서 *로 한것 배포시 수정해야함/ 허용할 도메인 주소 확인
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    credentials: true, // 쿠키를 사용하려면 true로 설정
    exposedHeaders: ['accessToken', 'refreshToken'],
  });
  
  
  
  이 에러는 credentials 를 false로 설정해서 에러가 뜸




트러블슈팅

회원가입시
"message": "비밀번호와 비밀번호 확인이 일치하지 않습니다."라는 에러가 에러로그에 뜬다.
 password 와 confirm이 문제가 생겨서 오류가가 생겼다.
프론트에서는 이 confirm 을 confirmPassword 로 받고있엇고 백앤드에서는 confirm으로 이것을 보내주고있어서
이름이 달라서 confirm 부분이 계속해서 에러가 뜨고있엇다..  코드의 이름을 통일을 생각하면서 작성필요

const { email, password, nickname, intro, confirmPassword, profileImg } = createUserDto;

    const user = await this.findByEmail({ email });
    if (user) {
      throw new ConflictException('이미 등록된 이메일입니다.');
    }
  // 리팩토링시 !== 로 변경
   if  (password != confirmPassword){
      throw new BadRequestException('비밀번호와 비밀번호 확인이 일치하지 않습니다.');
    }

   const hashedPassword = await bcrypt.hash(password, 10);

   return this.prisma.user.create({
      data: {
        email,
        password: hashedPassword,
        UserDetail: {
          create: {
            nickname,
            intro,
            profileImg,
          },
        }
      },
    });
  }
  
  프론트앤드에서 confirm 이 아니라 confirmPassword를 비밀번호 검증하는 변수로 사용중이어서 
계속해서 confirmPassword이 값이 언디파인드가 떳고 
백앤드 코드에서 confirm 부분을confirmPassword으로 전부수정해서 해결하였다.

 

 


그후 로그인시 
500번에러가 계속해서 뜨고있었는데 
프론트에서 staus 코드를 200번으로 설정해놓고 있었는데 swaager 에서는 201번으로 성공 코드를 보내주고있어서
프론트와 코드 staus가 맞지 않아 로그인이 되지않았다. staus코드를 무엇을 반환하는지 확인하고 정확히 api명세서에 
전달해야 할 것 같다.

이부분은 api 설계시에 로그인 성공을 200 staus 로 설정해놓았는데 
그때문에 프론트앤드에서 로그인성공 검증 로직 같은것을 구현할 때 
이 받아오는 코드가 if(staus === 200)이라면 같은 로직이 구성되어있어서
로그인이 되지않는 오류가 생겼다.

그래서 스웨거에서 로그인 성공 staus가 201로 설정되어있고 그에따라 프론트앤드의 코드를 변경
하여서 해결하였다.



또한 로그인을 성공했을때
엑세스토큰과 리프레시토큰 백앤드 헤더에서는 전달되는데 
프론트에서 네트워크에서는 엑세스토큰과 리프레시 토큰이 나오는데 
프론트에서 애플리케이션엔 undefind로 나왔다. 해결하기 위해서 정보를 검색 한 결과 
credentials: true 를 하면 프론트로 헤더에 있는 엑세스 토큰과 리프레시 토큰을 프론트앤드가 
받아서 사용할 수있다고 생각했는데  프론트앤드에서 헤더값을 받아올 수는 있어도 이것을 사용할 수가 없었다.
그래서 exposedHeaders: ['accessToken', 'refreshToken'], 라는 코드를 추가해서 
프론트앤드가 엑세스 토큰과 리프레시 토큰을 받을 수 있었다.

 exposedHeaders: ['authorization', 'authorization_refresh'],
authorization     로 프론트가 변수명을 선언했는데 백앤드에서 는 accessToken 으로 
authorization_refresh 로 프론트가 변수명을 선언했는데 백앤드에서 는 refreshToken 으로 
선언해서 헤더로 보냈기때문에
프로트앤드가   authorization ,authorization_refresh 로 응답을 받고있었기 때문에 되지않았다.

 프론트앤드에서 엑세스 토큰을 받아올때  authorization
리프리세 토큰을 받을때  authorization_refresh

코드를 작성하고있었는데 

백앤드 부분에서는 
accessToken
refreshToken
이 코드로 헤더부분에 보내주고있었다.

그래서 서로간의 코드가 전달되지않아서 
네트워크 부분에서는 엑세스토큰과 리프레시 토큰이 전달되고있엇지만

프론트앤드가 실제로 그 토큰을 사용하는 영역인 애플리케이션 부분에서는 
전부 undefinded 가 떳다.

프론트 부분은 authorization , authorization_refresh 이 코드를 accessToken
refreshToken 이 코드로 바꾸고 백앤드는 exposedHeaders: ['accessToken', 'refreshToken'],
를 사용해서 오류를 해결하였다.


  // CORS 설정
  app.enableCors({
    origin: 'http://localhost:5173',
    //origin: ['http://localhost:5173', 'http://localhost:3000'],
    //origin: '*', // 클라이언트 애플리케이션의 주소로 변경 개발단계라서 *로 한것 배포시 수정해야함/ 허용할 도메인 주소 확인
    methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
    credentials: true, // 쿠키를 사용하려면 true로 설정
    exposedHeaders: ['accessToken', 'refreshToken'],
  });
  
  
  그래서 최종적으로 cors해결을 할 백앤드 cors설정이다.


 exposedHeaders: ['accessToken', 'refreshToken'],