혼자 적어보는 노트

redux를 사용한 firebase Google, Github 로그인 / react-redux-firebase 본문

기타

redux를 사용한 firebase Google, Github 로그인 / react-redux-firebase

jinist 2022. 2. 10. 14:49

 

 

이전 포스팅에 이어서

이번엔 Google, Gitbut로그인을 진행해보려 한다.

 


 

Google 로그인

 

 

🔨Firebase setting

firebase console의 Authentication -  Sign-in method 에서 로그인 제공업체를 추가해준다.

 

 

 

✍ 코드작성

 

reducer의 상단에 이전에 만들어 두었던 provider 불러오기

import { auth, googleAuthProvider } from "../firebase";

 

[reducer.js]

 

ActionType과 Actions 작성

const GOOGLE_LOGIN_START = "GOOGLE_LOGIN_START";
const GOOGLE_LOGIN_SUCCESS = "GOOGLE_LOGIN_SUCCESS";
const GOOGLE_LOGIN_FAIL = "GOOGLE_LOGIN_FAIL";

const googleLoginStart = () => ({
  type: GOOGLE_LOGIN_START,
});

const googleLoginSuccess = (user) => ({
  type: GOOGLE_LOGIN_SUCCESS,
  payload: user,
});

const googleLoginFail = (error) => ({
  type: GOOGLE_LOGIN_FAIL,
  payload: error,
});

export const googleLoginInitiate = () => {
  return function (dispatch) {
    dispatch(googleLoginStart);
    auth
      .signInWithPopup(googleAuthProvider)
      .then(({ user }) => {
        console.log(user);
        dispatch(googleLoginSuccess(user));
      })
      .catch((error) => {
        console.log(error.message);
        dispatch(googleLoginFail(error.message));
      });
  };
};

 

reducer부분에 googleLogin 관련 action 추가

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case REGISTER_START:
    case LOGIN_START:
    case LOGOUT_START:
    case GOOGLE_LOGIN_START:
      return {
        ...state,
        loading: true,
      };
    case LOGOUT_SUCCESS:
      return {
        ...state,
        currentUser: null,
      };
    case REGISTER_SUCCESS:
    case LOGIN_SUCCESS:
    case GOOGLE_LOGIN_SUCCESS:
      return {
        ...state,
        loding: false,
        currentUser: action.payload,
      };
    case REGISTER_FAIL:
    case LOGIN_FAIL:
    case LOGOUT_FAIL:
    case GOOGLE_LOGIN_FAIL:
      return {
        ...state,
        loding: false,
        error: action.payload,
      };
    case SET_USER:
      return {
        ...state,
        loding: false,
        currentUser: action.payload,
      };
    default:
      return state;
  }
};

export default userReducer;

 

GoogleLogin 버튼에 이벤트 추가

import { googleLoginInitiate, loginInitiate } from "../modules/reducer";

const Login = (props) => {

  // ..생략

  const handleGoogleLogin = () => {
    dispatch(googleLoginInitiate());
  };

  return (
    // ..생략
  );
};

export default Login;

 

 

아주 간단하게 추가가 가능하다.

 

 


 

Github로그인

 

🔨Firebase setting

 

Github로그인도 Google로그인 처럼 해주면 되는데,

추가로 해주어야 될 부분이 있다.

위와 같이 Github로그인은 firebase console의 Authentication에서 추가할 때

클라이언트 ID와 보안 비밀번호가 필요하다.

 

아래의 회색 란에 있는 코드를 복사 한 후 Github에 접속한다.

 

 

 

Github 로그인 후 오른쪽 상단의 내 프로필을 눌러서 나오는 메뉴에서 Settings를 클릭한다.

 

 

왼쪽 메뉴의 하단에 Developer settings를 클릭한다.

 

OAuth App에서 New OAuth App을 클릭해준다.

 

Homepage URL은 자신의 도메인을 입력해주면 되는데,

local에서 사용할 경우 아무거나 입력해주어도 된다.

 

테스트를 하는 것이기 때문에 http://localhost:3000/로 입력했다.

 

그리고 맨 밑 Authorization callback URL에 아까 복사한 코드를 입력한다.

 

Register application을 클릭하면 Client ID와 Client secrets가 나타난다.

해당 부분을 복사해서 위의 입력란에 붙여넣어준다.

 

 

✍ 코드작성

 

reducer의 상단에 이전에 만들어 두었던 provider 불러오기

import { auth, googleAuthProvider, githubAuthProvider } from "../firebase";

 

const GITHUB_LOGIN_START = "GITHUB_LOGIN_START";
const GITHUB_LOGIN_SUCCESS = "GITHUB_LOGIN_SUCCESS";
const GITHUB_LOGIN_FAIL = "GITHUB_LOGIN_FAIL";

const githubLoginStart = () => ({
  type: GITHUB_LOGIN_START,
});

const githubLoginSuccess = (user) => ({
  type: GITHUB_LOGIN_SUCCESS,
  payload: user,
});

const githubLoginFail = (error) => ({
  type: GITHUB_LOGIN_FAIL,
  payload: error,
});

export const githubLoginInitiate = () => {
  return function (dispatch) {
    dispatch(githubLoginStart);
    auth
      .signInWithPopup(githubAuthProvider)
      .then(({ user }) => {
        console.log(user);
        dispatch(githubLoginSuccess(user));
      })
      .catch((error) => {
        console.log(error.message);
        dispatch(githubLoginFail(error.message));
      });
  };
};

 

reducer 코드 추가

 

const userReducer = (state = initialState, action) => {
  switch (action.type) {
    case REGISTER_START:
    case LOGIN_START:
    case LOGOUT_START:
    case GOOGLE_LOGIN_START:
      return {
        ...state,
        loading: true,
      };
    case LOGOUT_SUCCESS:
      return {
        ...state,
        currentUser: null,
      };
    case REGISTER_SUCCESS:
    case LOGIN_SUCCESS:
    case GOOGLE_LOGIN_SUCCESS:
      return {
        ...state,
        loding: false,
        currentUser: action.payload,
      };
    case REGISTER_FAIL:
    case LOGIN_FAIL:
    case LOGOUT_FAIL:
    case GOOGLE_LOGIN_FAIL:
      return {
        ...state,
        loding: false,
        error: action.payload,
      };
    case SET_USER:
      return {
        ...state,
        loding: false,
        currentUser: action.payload,
      };
    default:
      return state;
  }
};

export default userReducer;

 

Github Login 버튼에 이벤트 추가

Google Login 이벤트를 추가해 준 것 처럼 Github도 진행해준다.

import {
  googleLoginInitiate,
  githubLoginInitiate,
  loginInitiate,
} from "../modules/reducer";

const handleGithubLogin = () => {
    dispatch(githubLoginInitiate());
  };

 

 

형식이 비슷해서 다른 로그인 방식들도 응용해서 진행 하면 된다.

 


🙌  firebase v9 + async await

 

 

firebase.js에 provider를 생성해준다.

import { initializeApp } from "firebase/app";
import { GoogleAuthProvider, GithubAuthProvider } from "firebase/auth";

const firebaseConfig = {
  // ..config
};

export const firebaseApp = initializeApp(firebaseConfig);
export const googleProvider = new GoogleAuthProvider();
export const githubProvider = new GithubAuthProvider();

 

생성한 provider를 reducer에서 import해주어 사용을 해주는 방식이다.

 

[reducer.js]

import {
  getAuth,
  updateProfile,
  signInWithPopup,
} from "firebase/auth";

import { googleProvider, githubProvider } from "../lib/firebase/firebase";

// 생략

export const googleLoginInitiate = () => {
  return async function (dispatch) {
    dispatch(googleLoginStart());
    try {
      const auth = getAuth();
      const userCredential = await signInWithPopup(auth, googleProvider);
      dispatch(googleLoginSuccess(userCredential.user));
    } catch (error) {
      dispatch(googleLoginFail(error));
      console.log(error.code, "error code");
      console.log(error.message, "errorMessage");
    }
  };
};

export const githubLoginInitiate = () => {
  return async function (dispatch) {
    dispatch(githubLoginStart());
    try {
      const auth = getAuth();
      const userCredential = await signInWithPopup(auth, githubProvider);
      dispatch(githubLoginSuccess(userCredential.user));
    } catch (error) {
      dispatch(githubLoginFail(error));
      console.log(error.code, "error code");
      console.log(error.message, "errorMessage");
    }
  };
};

//..생략

 

Github displayName 추가

github의 경우 user의 데이터를 확인해보면 displayName이 null으로 체크된다.

user데이터를 보면 reloadUserInfo.screenName에 github의 name이 나타나는데

로그인시 displayName을 체크해 주고 없다면 update를 해주는 방식으로 displayName을 채워주었다.

export const githubLoginInitiate = () => {
  return async function (dispatch) {
    dispatch(githubLoginStart());
    try {
      const auth = getAuth();
      const userCredential = await signInWithPopup(auth, githubProvider);
      if (!userCredential.displayName) {
        await updateProfile(auth.currentUser, {
          displayName: userCredential.user.reloadUserInfo.screenName,
        });
      }
      dispatch(githubLoginSuccess(userCredential.user));
    } catch (error) {
      dispatch(githubLoginFail(error));
      console.log(error.code, "error code");
      console.log(error.message, "errorMessage");
    }
  };
};
Comments