개발/DB

[오류 해결]Error: Bind parameters must not contain undefined. To pass SQL NULL specify JS null

prpn97 2023. 6. 14. 17:21

어떻게 해결했는지는 가장 아래에 적었습니다.

 

 

프로젝트를 하면서 mysql을 처음 접하게 되었는데, sql문에 익숙하지 않다보니

저런 형식의 오류를 정말 많이 접했다. 구글링도 하고, gpt도 쓰면서 대부분의 오류들은 솔루션이

있었던지라 포스팅을 생각해본 적이 없었는데, 아무래도 오류 메세지만 봐서는 db문제라고

생각했는데 전혀 다른 곳에서 오류를 해결하게 되어서 포스팅하게 되었다. 

문제의 시작은 이렇다. 회원정보를 조회하는데, 프론트에서 불러오지 못한다고 듣게 되어서 

오류메세지를 봤더니, 계속해서 접했던 메세지기도 했고,

db에 맞닿는 부분이라 백엔드 오류임을 바로 알았다. 

 

오류가 있었던 코드를 살펴보자.

    const [rows] = await db.execute('SELECT * FROM user WHERE username = ?', [username]);

배열 안의 username값을 db에서 username이라는 컬럼 중에 찾는 것이다. 

 

Error: Bind parameters must not contain undefined.To pass SQL NULL specify JS null

 

"바인드 매개변수는 undefined를 포함해서는 안 됩니다.

SQL NULL을 전달하려면 JS에서 null을 지정하세요."


해석: SQL 쿼리의 바인드 매개변수에 undefined를 포함해서는 안 됩니다. 

대신에 SQL의 NULL 값을 전달하려면 JavaScript에서 null을 사용하세요.

 

이 값이 undefined일 때 생기는 오류라고 대신 null을 넣으라는 것이다. 

그런데, 여기서 username은 이미 로그인을 했기 때문에

로그인한 사용자의 값을 가져온 것이라 undefined가 나올 수가 없다. 

수정한 적도 없고 잘되다가 갑자기??

 

그리고 백엔드 쪽 오류가 아닐 수 있겠다고 의심을 하게 되었는데,

그 이유가 포스트맨에서 테스트했을 때에는 정상적으로 값을 불러왔다. 

서로 최신상태의 커밋을 풀해왔기 때문에 같은 상황에서 테스트한 것이고,

여러 경우의 수가 될법한 아이디로 로그인을 다 해보아도 값은 잘 불러왔다. 

 

물론 콘솔을 찍어서 undefined를 찾고 디버깅해볼 수는 있겠지만 애초에 포스트맨에서

정상적으로 값이 불러와지다보니 의심가는 부분만 확인해보니, 

req가 닿아있는 컨트롤러 쪽에서 undefined가 확인되었다.

물론 그마저도 나는 정상적으로 불러와졌다. 

 

그럼 도대체 무엇이 문제인가? 차이점은 포스트맨에서 테스트를 하냐, 

프론트에서 웹페이지에서 테스트를 하냐의 차이라고 생각했다. 

이 차이가 아니면 확연한 다른 차이는 찾아볼 수 없었다. 

에러메세지는 db값에 들어갈 값이 undefined라서 그런 것이고,

실제로 프론트에서 실행하는 과정에서 undefined가 나왔기 때문에

코드가 작동하면서 생기는 오류가 아닐까? 하는 합리적 의심이 들었다. 

비유하자면 연습과 실전은 다른 느낌? 이라고 생각했다.

 

문득 한 가지 떠오른 것이 있었다. 어제 해결한 것중에 로그아웃을 해도

토큰이 계속해서 남아있는 문제가 있었다. 토큰이 계속 남아있으면

로그아웃을 해도 인증된 상태로 서비스를 이용할 수 있는 것이니 큰 문제이고, 

지금 문제는 로그인을 했음에도 undefined로 확인하지 못하는 것이다보니

연관이 있지 않을까 싶었다. 로그아웃하면서 토큰을 삭제해준 방법은 다음과 같았다. 

프론트에서 로그아웃에 'withCredentials: true' 을 넣었을 때 쿠키가 삭제되는데,

그 이유는 withCredentials 옵션은 웹 요청을 보낼 때 쿠키와 인증 정보를

포함할 것인지를 설정하는 옵션이기 때문이다.

반대로 인증정보가 사라지면 쿠키도 사라지는 것이다. 

하필 어제 해결했던 것이 오늘 쓰이게 되었다. 

 

해결 방법     withCredentials: true

나의 경우에는 로그인한 이후 회원정보를 조회하는 과정에서 오류가 있었는데,

로그인할 때 토큰을 쿠키에 넣어주도록 로직을 구현했다.

 

 

서버에서 로그인 성공 시 HTTP-only 쿠키에 세션 ID나 JWT 토큰을 저장하여 

클라이언트에게 전송할 수 있다. 클라이언트의 브라우저는 이 쿠키를 저장하고,

이후 요청을 보낼 때 이 쿠키를 포함하여 보내는데, 이렇게 하면 서버는 쿠키를 통해

각 요청이 어떤 사용자로부터 온 것인지를 식별하고, 해당 사용자의 인증 상태를 관리할 수 있다.

 

프론트에서 withCredentials: true 옵션을 넣게 되면, 웹 요청을 보낼 때

쿠키와 인증정보를 포함하기 때문에 인증상태가 유효한데, 그렇지 않을 경우

로그인한 당시에는 쿠키가 유효하지만, 다른 페이지로 가면서 유효하지 않은 것이다.

그래서 undefined로 변한 것이다. 다음과 같은 위치에 추가하면 되겠다. 

추가하고 나니 인증정보가 유지되어 username에 undefined가 더 이상 나오지 않고

정상적으로 값이 조회되는 것을 확인했다. 

 

 

 

당연히 오류 자체가 db와 맞닿는 부분이라 백엔드에서 해결해야 하는 문제라고 생각했고,

구글링해도 대부분 쿼리에 값을 잘못 입력했거나 node의 버전에 관련한 내용 등

여러 다른 방법으로 해결했다는 글들을 보았는데, 결국 undefined가 들어갔다는 메세지이고,

그에 맞게 undefined가 아닌 정상적인 값을 넣도록 해결하는 것이 방법이다.

구글링해도 내가 원하는 솔루션이 나오기엔 힘들다. 왜냐하면 구현한 코드의 어딘가에서 

값을 제대로 반환하지 않기 때문이다. 위의 해결책도 하나의 방법일 뿐이다. 

 

 

728x90