라이브러리 없이 리액트에서 구글 로그인 구현하기 !

const job = '프론트엔드';·2023년 8월 25일
0
post-thumbnail

먼저, 간단한 로그인 form을 만들었다.

그런데 일단 구글 로그인'만'을 구현할거니깐, 사실 이건 필요없다는 사실을 구글 로그인을 구현하고 알아챘다.

그래서 간단하게 로그인 버튼을 만들어서 구글 로그인을 구현하려고 한다.

리액트로, 라이브러리 없이, 구글로그인 구현하기

1단계: 우선, https://console.cloud.google.com/ 에 접속
2단계: 새 프로젝트 생성하기

2-1. 새 프로젝트 이름 (마음대로 해도됨)

2-2. 클라이언트 ID, 클라이언트 PW받기

  • API 및 서비스 눌러서 들어감
  • 좌측 메뉴바에서 사용자 인증 정보 들어와서 상단에 '사용자 인증 정보 만들기' 누르고, 두번째 OAuth 클라이언트 ID를 누름
  • 동의하고
  • '외부' 선택
  • 필수 부분만 입력해서 만들기
  • 리액트 프로젝트니까 이렇게 딱 똑같이 설정하면 됨
  • 그러면 아마도 클라이언트 ID와 비밀번호가 발급되어 있음
  • 잘 숨겨두고
  • 로그인 기능을 구현할꺼니까, email부분만 체크하기(이 부분이 나중에 SCOPE부분 임)

준비 끝

그럼, 저 위에 구글로그인 버튼 만들어둔 .jsx(.js)파일에서 시작하겠음

필수로 필요한 기능(구조)

이 부분을 미리 읽어두면, 아래 작성 코드의 흐름이 이해하기가 쉬움

왜냐하면, 지금 이걸 적는 시점은 코드를 다 작성한 시점이기 때문임

✅ 사용자인증

  • 사용자가 애플리케이션에서 '구글 로그인 버튼'을 누름
  • OAuth2.0 인증 프로세스를 시작
  • 구글 인증 서버로 리다이렉션

✅ 사용자동의

  • 사용자에게 구글 계정에 로그인하라는 메세지표시
  • 사용자는 애플리케이션이 자신의 구글 데이터에 액세스하도록 동의

✅ 인증코드

  • 사용자 동의 후
  • 인증서버는 인증코드를 발급
    cf. code: 특정 인증 요청에 고유하게 부여된 권한과 연결됨

따라서, 코드는 사용자가 해당 애플리케이션(클라이언트, 브라우저)이 자신의 데이터에 엑세스하는 데 동의했다는 임시 증거, 인증코드는 한번만 사용할 수 있음

✅ 애플리케이션으로 다시 리다이렉션

  • 인증 서버는 URL에 쿼리 매개변수로 포함된 인증 코드와 함께 사용자를 애플리케이션에 지정된 애플리케이션이 호스팅되는 URI로 다시 리다이렉션

✅ 애플리케이션이 코드 캡쳐

  • 애플리케이션이 URL에서 인증 코드를 캡쳐

✅ 토큰교환

  • 애플리케이션은 인증 코드를 사용해서 인증 서버(구글 토큰 엔드포인트)에 안전하게 서버 간 요청을 보냄
  • 이 요청에서 애플리케이션은 인증 코드를 액세스 토큰 및 ID토큰으로 교환

✅ 액세스 토큰 및 ID토큰

  • 인증 서버는 코드의 유효성을 검사하고 유효한 경우 응답으로 액세스 토큰과 ID토큰을 발급
  • 이 토큰으로 애플리케이션에서 사용자의 액세스 토큰에 액세스 하거나 구글 API와 같은 보호된 리소스에 요청할 때 사용자를 식별하게 됨

기분이 이상하네....쉽지 않아

🖥 코드구현(순서대로만 따라하면 됨)

로그인 여부 상태 변수

  const [loggedIn, setLoggedIn] = useState(false);
  • 로그인 상태는 초기값이 false(로그인 안 된 상태임)
  • 만약에 true면 로그인이 된 상태(성공을 의미)

google oauth 구성 정보 정의

  const CLIENT_ID = process.env.REACT_APP_GOOGLE_ID;
  const REDIRECT_URI = "http://localhost:3000";
  const SCOPE = process.env.REACT_APP_GOOGLE_SCOPE;
  • .env에 담아놓고, 상수로 정의함

로그인 버튼 만들기

  return (
    <div>
      {loggedIn ? (
        <div>
          <p>Google로 로그인했습니다!</p>
        </div>
      ) : (
        <button onClick={handleGoogleLogin}>Google로 로그인</button>
      )}
    </div>
  );
};

export default GoogleLogin;
  • 로그인 여부 상태가 false면, 버튼이 보여지고
  • 로그인 여부 상태가 true면, 'Google로 로그인했습니다!' 메세지가 보여짐

버튼 클릭시 이벤트 생성

  const handleGoogleLogin = () => {
    const googleOAuthUrl = `https://accounts.google.com/o/oauth2/auth?client_id=${CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code&scope=${SCOPE}`;

   
    window.location.href = googleOAuthUrl;
  };
  • 버튼을 누르면 구글 OAuth URL을 생성하고, 구글 OAuth 동의 화면으로 리다이렉션

로그인 상태 변경하기

  useEffect(() => {
    // URL에 "code" 매개변수가 있는지 확인하여 Google 로그인이 성공했는지 여부를 확인
    const urlParams = new URLSearchParams(window.location.search);
    const authorizationCode = urlParams.get("code");

    //인증 코드가 있는 경우 사용자를 로그인된 것으로 간주하loggedIn 상태를 true로 설정
    if (authorizationCode) {
      setLoggedIn(true);
    }
  }, []); 
  • useEffect를 사용해서 최초 한 번만 실행되도록 했음
  • URL에 code매개 변수 여부로 구글 로그인이 성공했는지 확인
  • 인증 코드가 빈값이 아니라면 로그인 된 것으로 보고 true로 상태 변화

리다이렉션 컴포넌트 만들기(GoogleAuthRedirect.js)

axios / react-router-dom 임포트

npm install axios react-router-dom

useLocation으로 현재 위치(URL) 가져오고, useHistory를 사용해서 네비게이션을 위한 객체를 가져옴

  const location = useLocation();
  const history = useHistory();

code가 있는지 확인하고, 토큰을 교환하기 위한 POST요청을 수행
매개변수 파라미터 참고

useEffect(() => {
    const params = new URLSearchParams(location.search);
    const authorizationCode = params.get("code");

    if (authorizationCode) {
      // 인증 코드를 토큰으로 교환하기 위해 POST 요청
      const tokenEndpoint = "https://accounts.google.com/o/oauth2/token";
      const data = {
        code: authorizationCode,
        client_id: process.env.REACT_APP_GOOGLE_ID,
        client_secret: process.env.REACT_APP_GOOGLE_PW,
        redirect_uri: "http://localhost:3000/",
        grant_type: "authorization_code",
      };

      axios
        .post(tokenEndpoint, data)
        .then((response) => {
          const accessToken = response.data.access_token;
          const idToken = response.data.id_token;

          // 이 토큰들을 안전하게 저장

        
          history.push("/welcome");
        })
        .catch((error) => {
          // 에러 처리
        });
    }
  }, [location.search, history]);
  • 일단 코드가 있는지 확인(코드가 있다면, 구글 로그인에 성공한 것임)
  • 구글 로그인에 성공했다면(코드가 있다면), 인증코드를 토큰으로 교환해야 하므로 POST요청
  • 의존성 배열에 location.search는 URL의 현재 검색 부분을 나타냄
  • 따라서 URL의 쿼리 매개변수가 변경되면(그러니깐, 사용자가 구글 인증에서 다시 리다이렉션되고 URL에 새 코드 매개변수가 포함되는 경우 - 코드는 1회용이기 때문에), 새 코드를 처리하기 위해
  • history는 React Router의 기록 개체로 history 개체가 변경되면 적절한 탐색을 보장하기 위해 효과를 다시 실행

끝!

profile
`나는 ${job} 개발자`

0개의 댓글