게시글

5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭
강좌24 - NodeJS - 4년 전 등록

다른 도메인간 쿠키 전송하기(axios와 express 예제)

백엔드와 프론트엔드의 도메인 주소가 다른 경우가 많습니다. 이는 localhost인 경우에도 마찬가지입니다. 포트가 다르면 다른 주소로 칩니다. 이들간에는 쿠키 전송이 되지 않으므로 로그인이 유지되지 않아서 당황하시는 경우가 많습니다. 특히 개발자도구 Network 탭에서 Response Header에 Set-Cookie는 있는데 Application 탭에서 Cookie를 체크해보면 뜨지 않아서 어디가 문제인지 난처한 경우가 있습니다.

이럴 때 요청/응답 헤더를 적절하게 설정해주면 다른 도메인이더라도 쿠키가 전송됩니다.

먼저 프론트에서 ajax 요청을 보낼 때 withCredentials를 설정해주어야 합니다.

axios.post(주소, 데이터, { withCredentials: true });

순수한 xhr이라면 xhr.withCredentials = true를 추가하세요.

const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://example.com/', true);
xhr.withCredentials = true;
xhr.send(null); 

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials 

서버에서는 CORS 설정을 해주어야 하는데요. CORS 설정은 제 CORS 게시글을 참조바랍니다.

여기에 응답 헤더로 Access-Control-Allow-Credentials 옵션도 설정해주셔야 쿠키가 전송됩니다. Access-Control-Allow-Credentials를 true로 설정하고 Access-Control-Allow-Origin 옵션도 *가 아닌 정확한 도메인을 적어주면 됩니다.

express 사용 시 cors 모듈로 쉽게 설정할 수 있습니다.

const cors = require('cors');

app.use(cors({
  origin: true,
  credentials: true
}));

origin: true는 프론트 도메인 주소가 자동으로 Access-Control-Allow-Origin에 들어갑니다. 와일드카드인 *와는 다릅니다. credentials는 Access-Control-Allow-Origin을 true로 만들어주는 옵션입니다.

cors 모듈을 사용하지 않더라도 라우터에서 응답 헤더를 직접 넣어주시면 됩니다. 

res.setHeader('Access-Control-Allow-Origin', 'localhost:3000');
res.setHeader('Access-Control-Allow-Credentials', 'true'); 

https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials 

조회수:
0
목록
투표로 게시글에 관해 피드백을 해주시면 게시글 수정 시 반영됩니다. 오류가 있다면 어떤 부분에 오류가 있는지도 알려주세요! 잘못된 정보가 퍼져나가지 않도록 도와주세요.
Copyright 2016- . 무단 전재 및 재배포 금지. 출처 표기 시 인용 가능.
5만명이 선택한 평균 별점 4.9의 제로초 프로그래밍 강좌! 로드맵만 따라오면 됩니다! 클릭

댓글

4개의 댓글이 있습니다.
3년 전
제가 지금 nodejs책을 따라하면서 익스프레스로 sns서비스 만들기를 완료하였습니다.
axios.post(`/user/${userId}/unfollow`)로 언팔로우 버튼을 누를 때 작동하게 만들었는데 해당 라우터를 만들지 않아서 당연히 catch(error)로 error가 뜰거라고 예상했는데 catch에서 잡지를 못하더라구요. 원래 없는 페이지 요청은 catch로 잡을 수 없는 것인가요?

그리고 이건 다른 질문인데, html에서 사용된 console.log는 원래 terminal에는 안보이는건가요? chrome의 개발자 도구에서는 보이길래 여쭤봅니다.
3년 전
404에러가 뜰텐데 404에러는 catch에 잡힙니다. html에 사용된 콘솔로그는 브라우저에서만 보입니다.
3년 전
답변 정말 감사합니다.
저도 404 error가 나올거라 예상하였는데 pending상태로만 나옵니다. chrome의 개발자도구 network에서 status가 pending으로 나오지만 웹페이지가 로딩상태는 아닙니다.
3년 전
pending이 계속 이어지면 서버가 응답을 안 보내고 있는 겁니다. 또한 pending이더라도 ajax면 로딩이 뜨지는 않습니다.
4년 전
안녕하세요! 저번에 리액트 통신 관련해서 질문 남겼던 사람인데요
혹시 로컬에서 통신해볼때도 리액트 빌드한거를 서버 안에 넣어줘야하나요?
4년 전
아뇨 로컬에서는 빌드하실 필요 없습니다. 단 로컬은 localhost고 백엔드 서버가 실 서버면 ajax 통신이 안 될 수 있습니다. 그럴 때는 웹팩데브서버같은 것으로 프록시 서버 띄워두어야 합니다.
4년 전
리액트가 로컬이고 백엔드가 aws에 올라가 있을때 말씀하신거죠? 현재 프론트랑 서버 둘다 로컬로 통신 테스트하고 있는데요 쿠키는 이제 확인이 되었는데 로그인 후 user 정보만 전달이 안되네요ㅠㅠ서버에는 문제가 없는 것 같은데요ㅠㅠ
4년 전
혹시 새로고침할 때마다 쿠키가 달라지지는 않나요? 쿠키가 같다면 그 쿠키로 사용자 확인이 돼서 같은 사람이라고 서버가 인식합니다.
4년 전
지금 로컬로 테스트 중인데요! 로그인하고 브라우저 상에서 쿠키가 확인되었는데, 어떤 작업을 하려면 로그인 여부 미들웨어에서 걸려서 403 에러가 발생합니다ㅠㅠ 뭐가 문제인 걸까요? 쿠키 변화는 없는 상태이구요..
그리고 로그아웃해도 브라우저에 쿠키가 남아있던데 그건 맞는건가요?
4년 전
아뇨 로그아웃하면 쿠키가 사라져야합니다. 네트워크탭에서 쿠키메뉴를 봐보세요. 느낌표같은게 떠있지않나요?
4년 전
현재 확인해봤는데요. 느낌표 말씀하신게 warning 뜬 걸 말씀하신건지는 몰라도 확인해보니 다 리액트 쪽 오류인것 같네요.
확인해보니 로그인이 성공하면 쿠키가 만들어지고, req.user도 확인이 됩니다. req.user가 확인이 됬다는 것은 로그인 라우터에서 redirect되어 아래 라우터에 들어왔다는 건데,

router.get("/", (req, res, next) => {
res.send({ user: req.user, test: "테스트" });
});

현재 이 처리대로면 메인화면으로 넘어가지지 않고 그대로 로그인 화면이어서 리액트 쪽에서 메인화면으로 리다이렉트를 또 해주는데 그 과정에서 req.user가 확인이 안되네요. 이런 상황이면 제가 위 라우터에서 뷰를 렌더링 해줘야 되는건가요? 아니면 리액트 쪽에서 메인화면으로 리다이렉트할 때 user를 포함해서 해줘야되는건가요?
4년 전
음...쿠키는 브라우저가 알아서 포함시켜서 보내주는 거 아닌가요?? 요청보낼 때 req에서 cookies가 있는지 확인해보는데 null이 뜨네요. 이것때문에 유저를 인식 못하는 건지...
4년 전
도메인이 다르거나, cors설정이 다르거나 withCredentials같은 것을 설정하지 않았다면 쿠키가 전송되지 않습니다.
4년 전
안녕하세요. 현재 lightsail에 올라가 있는 node.js와 react 간에 통신 작업을 하고 있는데요!
문제가 있는 것이 로그인이 제대로 처리되지 않습니다ㅠㅠ
현재 교재(개정판아님)랑 똑같은 코드를 사용한 상태이구요. 위에 cors 설정도 했습니다.
그런데 서버에서 로그인 처리를 할 때는 아무 오류없이 로그인이 수행되는데(그 라우터에서 user를 확인하면 잘 뜹니다), 리액트에 user 값을 넘겨줄때는 빈 값이 전달되네요..
브라우저에서 쿠키를 확인해보면 비어있는 상태이구요..쿠키랑 세션을 사용하는데 문제가 있지 않은가 생각하는데..
express-session을 사용하는 상태에서 session과 쿠키를 직접 생성해서 클라이언트에게 보내줘야하나요??
알아서 만들어주고 쿠키도 전해주는 줄 알았는데요...
문제가 뭘까요...?
4년 전
express-session이 세션도 만들고 쿠키도 만든다는 것을 방금 이해했습니다. 그런데 왜 리액트에 넘겨줄때는 req.user가 비어있을까요??? 쿠키가 비어있는 이유는 httpOnly를 true라고 해서 그런거라고 이해해도 될까요?
4년 전
axios쓰시면 요청보낼 때 withCredentials 넣으셨나요? 서버쪽은 credentials cors 설정 하셨나요?
4년 전
네네
일단 리액트쪽은
axios.post('http://x.x.x.x/auth/login', { email: this.state.id, password: this.state.password }, { withCredentials: true, }
)
.then(
function (response) {
console.log(response);

})
.catch(error => {
alert("error")
console.log('error : ', error.response)

document.location.href = "/login";
});
이구요!
노드 쪽 cors는 이 게시글과 똑같이 설정했습니다.
4년 전
재밌는건, postman으로 테스트 작업 시 제대로 동작한다는 것입니다...뭐가 문제일까요ㅠㅠ
4년 전
아 혹시 리액트는 lightsail에 올리지 않았는데 올려야 되는건가요..ㅠㅠ리액트랑 통신은 처음이라 어렵네요ㅠㅠ올린다면 어디에 두면 될까요...
4년 전
리액트도 빌드해서 라이트세일에 올려서 node가 제공하게 하면 됩니다. 아마 지금 안 되는 것은 node는 실 서버 주소이고, react는 localhost여서 그런 것 같네요.
4년 전
답변 감사합니다!
그렇다면 같은 서버에 올리면 될까요? node 서버 디렉토리에 있는 views 폴더에 pug 파일 넣는 것 처럼요?
4년 전
네네 빌드하면 js랑 html나올텐데 public 폴더에 넣으시고 express.static 연결하시면 됩니다.
4년 전
안녕하세요! 제로초님 axios로 설정할 때 withCredentials 과 credentials 둘 다 써도 상관 없는 건가요? 검색해보니까 axios 일때는 withCredentials 로 해야된다는 글들이 좀 있어서요!
4년 전
withCredentials입니다! 오타를 냈네요. 감사합니다.