๐ŸŒŸ Oauth: Social Login

summereuna๐Ÿฅยท2022๋…„ 3์›” 30์ผ

๐ŸŒŸ Twinkle (React, Firebase)

๋ชฉ๋ก ๋ณด๊ธฐ
9/42

Social(๊ตฌ๊ธ€/๊นƒํ—™) ๋กœ๊ทธ์ธ ๊ตฌํ˜„

signInWithPopup()

ํŒ์—… ๊ธฐ๋ฐ˜ OAuth ์ธ์ฆ ํ๋ฆ„์„ ์‚ฌ์šฉํ•˜์—ฌ Firebase ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ธ์ฆํ•œ๋‹ค. ์ฆ‰, ํŒ์—…์ฐฝ ์—ด์–ด ๋กœ๊ทธ์ธ ์ธ์ฆ์„ ํ•˜๋Š” ๋ฉ”์„œ๋“œ์ด๋‹ค.

  • ์„ฑ๊ณตํ•˜๋ฉด ๊ณต๊ธ‰์ž์˜ ์ž๊ฒฉ ์ฆ๋ช…๊ณผ ํ•จ๊ป˜ ๋กœ๊ทธ์ธํ•œ ์‚ฌ์šฉ์ž๋ฅผ ๋ฐ˜ํ™˜
  • ๋กœ๊ทธ์ธ์— ์‹คํŒจํ•œ ๊ฒฝ์šฐ ์˜ค๋ฅ˜์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ •๋ณด๊ฐ€ ๋“ค์–ด ์žˆ๋Š” ์˜ค๋ฅ˜ ๊ฐœ์ฒด๋ฅผ ๋ฐ˜ํ™˜
  • (์ฐธ๊ณ )
    signInWithRedirect()๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋””๋ ‰์…˜ํ•˜์—ฌ ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜๋„๋ก ์š”์ฒญํ•œ๋‹ค. ๋ฆฌ๋””๋ ‰์…˜ ๋ฐฉ๋ฒ•์€ ๋ชจ๋ฐ”์ผ ์žฅ์น˜์—์„œ ์„ ํ˜ธ๋œ๋‹ค.
export declare function signInWithPopup(auth: Auth, provider: AuthProvider, resolver?: PopupRedirectResolver): Promise<UserCredential>;
ParameterTypeDescription
authAuthThe Auth instance.
providerAuthProvider์ธ์ฆํ•  ๊ณต๊ธ‰์ž. ๊ณต๊ธ‰์ž๋Š” OAuthProvider์—ฌ์•ผ ํ•œ๋‹ค. EmailAuthProvider์™€ ๊ฐ™์€ OAuth๊ฐ€ ์•„๋‹Œ ๊ณต๊ธ‰์ž๋Š” ์˜ค๋ฅ˜๋ฅผ ๋ฐœ์ƒ์‹œํ‚จ๋‹ค.
resolverPopupRedirectResolverPopupRedirectResolver์˜ ์ธ์Šคํ„ด์Šค. ์ด๋ฏธ initializeAuth()์— ์ œ๊ณต๋˜๊ฑฐ๋‚˜ getAuth()์— ์˜ํ•ด ์ œ๊ณต๋  ๊ฒฝ์šฐ์—๋Š” ์˜ต์…”๋„ํ•˜๋‹ค.

1. GoogleAuthProvider()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Firebase๋กœ ์ธ์ฆํ•˜๊ธฐ

  • Google provider object๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Firebase๋กœ ์ธ์ฆํ•œ๋‹ค.

signInWithPopup()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒ์—… ์ฐฝ์„ ์—ด์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ Google ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๋„๋ก ์š”์ฒญํ•˜๊ธฐ

import { getAuth, signInWithPopup, GoogleAuthProvider } from "firebase/auth";
//
const auth = getAuth();
signInWithPopup(auth, provider)
  .then((result) => {
    // This gives you a Google Access Token. You can use it to access the Google API.
    const credential = GoogleAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;
    // The signed-in user info.
    const user = result.user;
    // ...
  }).catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
    // The email of the user's account used.
    const email = error.email;
    // The AuthCredential type that was used.
    const credential = GoogleAuthProvider.credentialFromError(error);
    // ...
  });

2. GithubAuthProvider()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Firebase๋กœ ์ธ์ฆํ•˜๊ธฐ

  • GitHub provider object๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Firebase๋กœ ์ธ์ฆํ•œ๋‹ค.

signInWithPopup()๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํŒ์—… ์ฐฝ์„ ์—ด์–ด ์‚ฌ์šฉ์ž์—๊ฒŒ GitHub ๊ณ„์ •์œผ๋กœ ๋กœ๊ทธ์ธํ•˜๋„๋ก ์š”์ฒญํ•˜๊ธฐ

import { getAuth, signInWithPopup, GithubAuthProvider } from "firebase/auth";
//
const auth = getAuth();
signInWithPopup(auth, provider)
  .then((result) => {
    // This gives you a GitHub Access Token. You can use it to access the GitHub API.
    const credential = GithubAuthProvider.credentialFromResult(result);
    const token = credential.accessToken;
    // The signed-in user info.
    const user = result.user;
    // ...
  }).catch((error) => {
    // Handle Errors here.
    const errorCode = error.code;
    const errorMessage = error.message;
    // The email of the user's account used.
    const email = error.email;
    // The AuthCredential type that was used.
    const credential = GithubAuthProvider.credentialFromError(error);
    // ...
  });

๋ณด์•„ํ•˜๋‹ˆ ๊ตฌ๊ธ€/๊นƒํ—™ ํ”„๋กœ๋ฐ”์ด๋” ๋ฐฉ์‹ ๋‘˜ ๋‹ค ๋˜‘๊ฐ™๋‹ค.

๐Ÿ“/routes/Auth.js

1. ์†Œ์…œ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์— name ์ถ”๊ฐ€

<div>
  <button name="google">Google ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ</button>
  <button name="gitHub">GitHub ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ</button>
</div>

2. ์†Œ์…œ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด ์‹คํ–‰๋  ํ•จ์ˆ˜ ์ƒ์„ฑ

const onSocialClick = (event) => {
  console.log(event.target.name);
};

3. ์†Œ์…œ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์— onClick ์ด๋ฒคํŠธ ์‹คํ–‰์‹œ onSocialClick ํ•จ์ˆ˜ ์‹คํ–‰๋˜๋„๋ก ์ถ”๊ฐ€

<div>
  <button name="google" onClick={onSocialClick}>
    Google ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ
  </button>
  <button name="gitHub" onClick={onSocialClick}>
    GitHub ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ
  </button>
</div>

4. ํŒ์—…์œผ๋กœ ๋กœ๊ทธ์ธ ํ•˜๋„๋ก ์„ค์ •

import { useState } from "react";

//์ด๋ฉ”์ผ, ๋น„๋ฒˆ์œผ๋กœ ์ƒˆ๋กœ์šด ๊ณ„์ • ์ƒ์„ฑ ๋ฐ ๋กœ๊ทธ์ธ ํ•˜๊ธฐ์œ„ํ•ด ์•„๋ž˜ ๋ฉ”์„œ๋“œ ์ž„ํฌํŠธํ•˜๊ธฐ
//getAuth, createUserWithEmailAndPassword, signInWithEmailAndPassword
import {
  getAuth,
  createUserWithEmailAndPassword,
  signInWithEmailAndPassword,
  GoogleAuthProvider,
  GithubAuthProvider,
  signInWithPopup,
} from "firebase/auth";

const Auth = () => {
  const [email, setEmail] = useState("");
  const [password, setPassword] = useState("");
  const [newAccount, setNewAccount] = useState(true);
  //error ์Šคํ…Œ์ด๋“œ๋ฅผ ๋งŒ๋“ค์ž. ๋””ํดํŠธ ๊ฐ’์œผ๋กœ ๋น„์–ด ์žˆ๋Š” ํ…์ŠคํŠธ ์ฃผ๊ธฐ
  const [error, setError] = useState("");

  const auth = getAuth();

  //email, password์— ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฒคํŠธ
  const onChange = (event) => {
    const {
      target: { name, value },
    } = event;
    if (name === "email") {
      setEmail(value);
    } else if (name === "password") {
      setPassword(value);
    }
  };

  //form์— ์‚ฌ์šฉํ•˜๋Š” ์ด๋ฒคํŠธ
  const onSubmit = async (event) => {
    event.preventDefault();
    //form submitํ•˜๋ฉด newAccount ์Šคํ…Œ์ดํŠธ๋กœ ํ™•์ธํ•˜์ž!
    //newAccount๊ฐ€ ์ฐธ์ด๋ฉด ๊ณ„์ • ์ƒˆ๋กœ ๋งŒ๋“ค๊ณ , ๊ฑฐ์ง“์ด๋ฉด ๋กœ๊ทธ์ธํ•˜๊ธฐ
    try {
      if (newAccount) {
        await createUserWithEmailAndPassword(auth, email, password);
        setNewAccount(false);
      } else {
        await signInWithEmailAndPassword(auth, email, password);
      }
    } catch (error) {
      //์—๋Ÿฌ๊ฐ€ ์ƒ๊ธฐ๋ฉด error ์Šคํ…Œ์ดํŠธ์— ๋„ฃ์–ด์„œ ์—๋Ÿฌ ๋ฉ”์„ธ์ง€ ๋„์šฐ๊ธฐ
      //console.log(error.message);
      setError(error.message);
    }
  };

  //๊ฐ€์ž…ํ•ด์•ผํ•˜๋Š”์ง€ ๋กœ๊ทธ์ธํ•ด์•ผ ํ•˜๋Š”์ง€ ํ† ๊ธ€ํ•˜๋Š” ํ•จ์ˆ˜: newAccount์˜ ์ด์ „ ๊ฐ’๊ณผ ๋ฐ˜๋Œ€๋˜๋Š” ๊ฐ’ ๋ฆฌํ„ดํ•˜๊ธฐ
  const toggleAccount = () => setNewAccount((prev) => !prev);

  //๐Ÿ”ฅ๐Ÿ”ฅ์†Œ์…œ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ ํด๋ฆญํ•˜๋ฉด ์‹คํ–‰๋  ํ•จ์ˆ˜ ์ƒ์„ฑ
  const onSocialClick = async (event) => {
    //console.log(event.target.name);
    const {
      target: { name },
    } = event;
    let provider;
    //๐Ÿ”ฅ๐Ÿ”ฅํƒ€๊ฒŸ์˜ name์— ๋”ฐ๋ผ(์ฆ‰, ๋ฌด์Šจ ๋ฒ„ํŠผ์ด ๋ˆŒ๋ฆฌ๋Š”์ง€์— ๋”ฐ๋ผ)
    if (name === "google") {
      //๐Ÿ”ฅprovider ๊ตฌ๊ธ€๋กœ ์„ค์ •
      provider = new GoogleAuthProvider();
    } else if (name === "github") {
      //๐Ÿ”ฅprovider ๊นƒํ—™์œผ๋กœ ์„ค์ •
      provider = new GithubAuthProvider();
    }
    await signInWithPopup(auth, provider);
  };

  return (
    <div>
      <h1>๋กœ๊ทธ์ธ ํŽ˜์ด์ง€</h1>
      <p>๋กœ๊ณ  ๋„ฃ๊ธฐ</p>
      <form onSubmit={onSubmit}>
        <input
          type="email"
          placeholder="์ด๋ฉ”์ผ"
          required
          value={email}
          name="email"
          onChange={onChange}
        ></input>
        <input
          type="password"
          placeholder="๋น„๋ฐ€๋ฒˆํ˜ธ"
          required
          value={password}
          name="password"
          onChange={onChange}
        ></input>
        <input type="submit" value={newAccount ? "๊ฐ€์ž…ํ•˜๊ธฐ" : "๋กœ๊ทธ์ธ"} />
        {/*error ๋ณด์—ฌ์ฃผ๊ธฐ*/}
        {error}
      </form>
      {/*newAccount(์ƒˆ๋กœ์šด ๊ณ„์ •)๊ฐ€ ์ฐธ์ด๋ฉด ๋กœ๊ทธ์ธ, ๊ฑฐ์ง“์ด๋ฉด ๊ฐ€์ž…ํ•˜๊ธฐ๊ฐ€ ๋˜๋Š” ํ† ๊ธ€ ๋งŒ๋“ค๊ธฐ */}
      <button onClick={toggleAccount}>
        {newAccount ? "๋กœ๊ทธ์ธ" : "๊ฐ€์ž…ํ•˜๊ธฐ"}
      </button>
      <div>
        {/*๐Ÿ”ฅ ๋ฒ„ํŠผ ๋งŒ๋“ค๊ณ  onClick ์ด๋ฒคํŠธ์— onSocialClick ํ•จ์ˆ˜ ์—ฐ๊ฒฐ*/}
        <button name="google" onClick={onSocialClick}>
          Google ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ
        </button>
        <button name="github" onClick={onSocialClick}>
          GitHub ๊ณ„์ •์œผ๋กœ ๊ณ„์†ํ•˜๊ธฐ
        </button>
      </div>
    </div>
  );
};

export default Auth;
profile
Always have hope๐Ÿ€ & constant passion๐Ÿ”ฅ

0๊ฐœ์˜ ๋Œ“๊ธ€