상태코드 이해하기
서버는 클라이언트 요청에 대해 알맞은 status code를 보내주어야 한다.
자주 쓰는 코드는 200
, 201
, 204
, 400
, 401
, 403
, 404
등이 있는데, 이중에서 몇몇 상태코드의 의미를 혼동해 사용하게 된다. 로그인 또는 auth 인증 등에서는 특히 다양한 상태코드를 쓰게되는데, 어떤 상황에서 어떤 코드를 보내는 것이 적절한지 정리해보려한다.
서버가 클라이언트 오류를 감지해 요청을 처리할 수 없거나, 하지 않는 다는 것을 의미한다. 여기서 클라이언트 오류란, 클라이언트에서 필수로 전달해줘야하는 파라미터가 부족하거나 존재하지 않는 파라미터를 보낸 경우 등이 있다.
예를 들어, auth 요청에서 클라이언트의 쿠키에 accessToken (req.cookies.accessToken)이 없는 경우이다.
const { accessToken } = req.cookies;
if (!accessToken) {
return res.status(400).json({
error: {
path: "/user/auth",
message: "no accessToken",
},
});
해당 리소스에 대한 인증자격증명(액세스 토큰 등)이 유효하지 않아서 요청이 적용되지 않았음을 나타낸다. (액세스 토큰이 이상하단 뜻)
다음은 req.cookies.accessToken으로 전달받은 인증자격증명을 복호화가 되지 않은 경우이다. 즉, 쿠키에 accessToken은 담겼지만, 서버에서 암호화한 것이 아닌 잘못된 accessToken인 경우이다.
const verified = jwt.verify(
accessToken,
process.env.ACCESS_SECRET,
(err, decoded) => {
if (err) return null;
return decoded;
}
);
//accessToken은 있지만 해독되지 않는 경우
if (!verified) {
return res.status(401).json({
error: {
path: "/user/auth",
message: "invalid accessToken",
},
});
}
서버에 요청이 전달되었지만, 권한때문에 거절되었다는 것을 의미한다. 특정 리소스에 접근하거나 요청을 수행할때, 권한이 필요한 경우가 있다.
예를들어, 다른 유저가 작성한 게시물을 삭제하려고 한다면, 이때는 403
상태코드를 전달해야할 것이다.
클라이언트에서 필수로 전달하기로 한 파라미터를 전달하긴 했지만 (따라서400
아님), 서버에서 요청받은 리소스를 찾을 수 없는 경우이다. 즉, 존재해야할 리소스가 없으므로 에러인 것이다.
단, 404
는 원래 있던 리소스가 일시적 또는 영구적으로 사라졌다는 것을 의미하지는 않는다. 리소스가 영구적으로 삭제되었다면 404
가 아닌 410 GONE
상태코드를 써야한다.
microsoft에서는 다음과 같은 원인으로 HTTP 404 에러가 발생한다고 설명한다.
따라서, 클라이언트에서 데이터를 요청(GET)할때, 서버에 실제로 보내줄 데이터가 없다면 에러가 아니다. 다시 말해, 있어야할 데이터가 없다면 에러가 맞지만, 보내줄 데이터가 원래 없었다면 요청 자체는 성공한 것이므로 (에러가 아니므로) 200번대 코드를 보내야한다. 이때는 다음의 상태코드(204
)를 보내줄 수 있다.
요청이 성공했으나 서버에서 전달할 데이터가 없는 경우이다. 기존에 나는 클라이언트에서 PUT, PATCH, DELETE 요청을 보낸 경우, 서버에서 DB의 데이터를 변경하고, 나서 204
상태코드를 보내는 것이라고 이해를 했었다.
그런데, 다양한 글들을 보니 요청자체는 성공했지만, 보내줄 데이터가 없는 경우에도 200
대신 204
를 쓰는 것 같다.
MDN에서는 다음과 같이 설명한다.
흔히 204를 반환하는 경우는 PUT요청에 대한 응답으로, 사용자에게 보여지는 페이지를 바꾸지 않고 리소스를 업데이트할 때 쓰입니다. 리소스를 생성한 경우엔 201 Created를 대신 반환합니다. 새롭게 업데이트한 페이지를 보여줘야할 경우 200을 사용해야합니다.
따라서, 업데이트한 페이지를 보여주지 않아도 될 경우, 200
에 빈배열을 보내줄 수도 있고, 204
에 바디를 보내지 않을 수 있다.
요청이 성공했음을 나타내며 기본값에서 200
은 캐시에 저장할 수 있다. 204
와 다르게 데이터가 없을경우 빈배열을, 데이터가 있다면 데이터를 바디에 전달할 수 있다.
reference