facebook social login, passport cors 에러 해결

Matthew Woo·2021년 3월 24일
0
post-thumbnail

express, nodejs, react로 facebook Login 구현하다가 cors에 막혀서 이를 정리해보고 가고자 한다.
signin.js

const fbLoginBtn = () => {
	//action
        dispatch(fblogin()); 
    }
    return(
        <>  
            <Layout />
            <button onClick={fbLoginBtn}>facebook login</button>
        </>
    )    

userAction.js

export const fblogin = () => {
    return async (dispatch) => {
        dispatch({ type: "FACEBOOK_LOGIN_REQUEST"});
        try {
        	// facebook 로그인 요청
            const res = await axiosInstance.get('auth/facebook/callback');
            if(res.status === 200) {
                const { data } = res;
                console.log(data);
                dispatch({
                    type: "FACEBOOK_LOGIN_SUCCESS",
                })
            }
        } catch(err) {
            console.log(err);
        }
    }
} 

에러내용..ㅠㅠ

3000포트(frontemd에서 -Btn 클릭) 에서 axios로 2000포트(backend)로 접근하면, backend의

router.get('/auth/facebook', passport.authenticate('facebook')); 가 실행.

facebook 인증이 진행되어야 하는데 facebook 서버가 2000 port로부터의 XMLHttpRequest access를 허용하지 않기에cors에 막히는 것 이다.
(아니면 댓글로 알려주세요..!!)

그래서 해결책은 front 에서 facebook측에 요청을하면서 axios를 이용한 XMLHttpRequest 요청이 아닌 href 요청을 한다.

<a href="http://localhost:2000/api/auth/facebook">
                <button>facebook login</button>
</a>

axios로 2000 backend요청을 한 것이 아닌 href로 접근한다.

href 요청에 성공하여 유저 정보도 받아오고 accessToken값을 받아오고 위 스샷의 FacebookStrategy도 실행 된 이후 serialize 함수도 잘 작동한다.

그래서 그 다음은..? 그래서 그 다음은?????

여태 해왔던 프로젝트들은 한 개의 포트 내에서 (ex) localhost:3000 만 진행을 했던 지라 여기서
serialize deserialize함수를 이용하여
serialize가 로그인 후 1회 실행되어 session에 정보를 넣어주고 다른 url로 넘어가거나 새로 load를 할 떄마다
deserialize가 실행되면서 deserialize cb(null, obj)로 전달한 obj(주로 user)를 req에 넣어주었다.
그럼 route들을 이동할 떄 마다 reqdeserialize가 실행되어 전달한 obj가 있는지의 여부로 유저정보 및 로그인 유무를 파악하였는데....

헌데 이번 프로젝트같은경우 localhost:3000 backend, localhost:2000 front가 따로 돌아가고 있다...
front(2000)에서 페이지나 화면이 전환될 떄마다 back측에 일일히 로그인 여부를 요청할 수는 없고...

  1. 이 경우에는 어떻게 해줘야하는지..

일단 내 예상은 accessToken을 front(2000)쪽에 넘겨주고 accessToken2000(front)쪽에서 redux-store 로 갖고있다가 backend 쪽에 다시 무언가를 요청할 때는 그 accessToken과 함께 요청하여 해당 accessToken이 유효하면 해당 요청에 응답한다.

  1. 그럼 여기서 serialize, deserialize는 왜 필요하지?

..누가 알려주세요 ...

accessToken과 함께 front쪽에서 back쪽으로 요청이 들어올 때 마다 deserialize가 실행되고 해당 토큰이 유효한지 검사된 뒤에 해당 요청에 응답해주는건가?

serializesessiontoken을 넣어놨으니 deserializesession에서 해당 토큰값을 꺼내와서 요청과 함께 들어온 token값과 비교하여 맞으면 실행되는건가..? deserialize는 해당 session에서 serialize로 넣어준 값을 받아와서 req에 넣는건데..

req.obj(token) 와 front에서 넘어온 token값을 비교해주면 되는것인가...!!

그리고 accessToken은 2000포트에 전달해주면서 어떻게 redux action, store에 넣어준담?(요건 구글링으로 해결) (넣어주는 방법 링크)

흐어어엉 결국 다 해결했다. 근데 문득 드는 의문점.
token값을 redux-store에도 넣어주고 localStorage에도 저장하긴했는데 token값을 왜 두 곳에서 들고 있어야하지?
redux에만 저장시켜놓거나 localStorage에만 넣어주면 되는거 아닌가. 그럼 두개는 무슨 장단점이 있으련지.
정석은 localStorage일텐데

profile
Code Everyday

0개의 댓글