[react]Google Firebaseを使用した電子メール/パスワード認証ログイン機能の作成(feat.雑誌サイトの作成)

35817 ワード

ログイン機能の実装


ログインの作成
1. firebase.jsで作成したauthをインポート
2.reduceからloginFB関数を作成する
3. auth.signInWithEmailAndPassword()でログイン
4.Login構成部品からLoginFBを呼び出す!
5.Ridexのユーザー情報を更新してホームページに移動

1. firebase.jsで作成したauthをインポート

//firebase.js
import firebase from 'firebase/compat/app'; 
import 'firebase/compat/auth'; 
import 'firebase/compat/firestore';

// Your web app's Firebase configuration
const firebaseConfig = {
  apiKey: "---",
  authDomain: "---"
  projectId: "---",
  storageBucket: "---",
  messagingSenderId: "---",
  appId: "---"
};

// Initialize Firebase
firebase.initializeApp(firebaseConfig);

//firebase 인증 가져와서 쓰기
const auth = firebase.auth();

export {auth};
  • auth導入
  • //user.js
    import { auth } from "../../shared/firebase";

    2.reduceからloginFB関数を作成する

    //user.js
    //Action
    const LOG_IN = "LOG_IN";
    const loginFB = (id, pwd) => {
        return function ( dispatch, getState, { history }){
            
        }
    }

    3. auth.signInWithEmailAndPassword()でログイン


    -電子メールアドレスとパスワードを使用してユーザーログインを処理

    //user.js
    const loginFB = (id, pwd) => {
        return function ( dispatch, getState, { history }){
            
            signInWithEmailAndPassword(auth, id, pwd)
            .then((user) => {
            // Signed in
                console.log(user); // user_name 바꿔주려고 콘솔창에 찍어봄
                dispatch(setUser({id: id, user_name: user.user.displayName, user_profile: ''}));
                history.push("/");  // 로그인하면 바로 메인페이지 이동
            // ...
            })
            .catch((error) => {
                const errorCode = error.code;
                const errorMessage = error.message;
                console.log(errorMessage);
            });
          
        }
    }

    4.Login構成部品からLoginFBを呼び出す!

    //login.js
    const Login = (props) => {
        const dispatch = useDispatch();
        
      //useState()로 id와 pwd state 받아와서 수정
        const [id, setId] = React.useState();
        const [pwd, setPwd] = React.useState();
    
        const loginID = (e) => {
            setId(e.target.value);
        }
        const loginPWD = (e) => {
            setPwd(e.target.value);
        }
    
        const logIn = () => {
            if(id === '' || pwd === ''){
                window.alert("아이디 혹은 비밀번호를 입력해주세요.");
            }
            dispatch(userActions.loginFB(id, pwd));
        }
    
        return (
            <Wrap>
                <h1>Log In</h1>
                <div>
                    <div>
                        <label htmlFor="id">ID</label><br />
                        <Input id="id" value={id} _onChange={loginID} type="text" placeholder="Please enter your ID" /><br />
                        <label htmlFor="password">Password</label><br />
                        <Input id="password" value={pwd} _onChange={loginPWD} type="password" placeholder="Please enter your Password"/><br />
                    </div>
                    <br />
    
                    <div>
                        <Button style={{width: "300px"}}  
                                variant="contained" color="secondary"
                                onClick={() => {logIn()}}>Log In</Button>
                    </div>
                </div>
            </Wrap>
        )
    }

    5.Ridexのユーザー情報を更新してホームページに移動


    -user.jsではloginFB()でdispatch後のhistory.push("/");をホームページに入れる

    ログイン・メンテナンスの実施


    1.ログイン時にセッションにログイン状態を記録させる


    セッションにログイン情報を記録させ、ログインするたびにセキュリティが失われたりリフレッシュされたりしてログアウトしないようにします.
    const loginFB = (id, pwd) => {
        return function ( dispatch, getState, { history }){
          // 이부분을 사용해서 session에 정보 삽입
            << setPersistence(auth, browserSessionPersistence)
            .then(() => { >>  
                // Existing and future Auth states are now persisted in the current
                // session only. Closing the window would clear any existing state even
                // if a user forgets to sign out.
                // ...
                // New sign-in will be persisted with session persistence.
                signInWithEmailAndPassword(auth, id, pwd)
                .then((user) => {
                // Signed in
                    console.log(user);
                    dispatch(setUser({
                        id: id, 
                        user_name: user.user.displayName, 
                        user_profile: '',
                    }));
                    history.push("/");
                })
                .catch((error) => {
                    const errorCode = error.code;
                    const errorMessage = error.message;
                    console.log(errorCode, errorMessage);
                });
              
            })
            
        }
    }

    2.loginCheckFB()の作成

    //user.js
    const loginCheckFB = () => {
        return function ( dispatch, getState ){
            onAuthStateChanged(auth, (user) => {
                if (user){         
                    dispatch(setUser({
                        id: user.email,
                        user_name: user.displayName.replace,
                        user_profile: "", 
                        uid: user.uid,
                    }))        
                  // User is signed in, see docs for a list of available properties
                } else {
                  // User is signed out
                  dispatch(logOut());
                }
              
            }          
        )}
    }

    3.Firebase認証鍵のエクスポート

    //firebase.js
    ...
    const apiKey = firebaseConfig.apiKey;
    
    export {auth, apiKey};

    4.ログイン状態を維持するためにセッションをチェックする


    App.jsはheadjsより起点にあるので、最初からアプリをチェック.jsは会話をチェックしてあげます.
    //App.js
    import { actionCreators as userActions } from "./redux/modules/user";
    import { loginCheckFB } from "./redux/modules/user";
    import { apiKey } from "./shared/firebase";
    
    function App() {
        const history = useHistory();
        const dispatch = useDispatch();
        const is_login = useSelector((state) => state.user.is_login);  // redux store에 is_login이 true인지 false인지 가져옴
        const session_key = `firebase:authUser:${apiKey}:[DEFAULT]`;
       
        const is_session = sessionStorage.getItem(session_key) ? true : false;
        console.log(is_session);
        React.useEffect((is_session) =>{
            dispatch(userActions.loginCheckFB()); // 세션에 값있으면 loginCheckFB
        })
    }

    5.Firebaseによるログインの確認