17
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

FirebaseとReactで認証実装

Posted at

FirebaseとReactを使って認証機能実装

プログラミング初心者が認証機能を実装したので備忘録として残しておきます。

使ったもの

  • react-router
  • Firebase Authentication
  • Hooks

Firebaseの設定

まずFirebaseでプロジェクトを作成し、Authenticationを有効化します。
今回は"メール/パスワード"を使いました。
そして、プロジェクトのSettingsから自分のappsのFirebase SDK snippetのConfigをコピーします。
以下のような形で取得できると思います。

const firebaseConfig = {
 apiKey: "your_key",
 authDomain: "your_app_id.firebaseapp.com",
 databaseURL: "https://your_app_id.firebaseio.com",
 projectId: "your_app_id",
 storageBucket: "your_storage_bucket",
 messagingSenderId: "sender_id",
 appId: "your_app_id"
};

これを、自分のアプリのルートディレクトリに.envファイルを作って以下の形式で保存します。

/.env
REACT_APP_FIREBASE_KEY=your_key
REACT_APP_FIREBASE_DOMAIN=your_app_id.firebaseapp.com
REACT_APP_FIREBASE_DATABASE=https://your_app_id.firebaseio.com
REACT_APP_FIREBASE_PROJECT_ID=your_app_id
REACT_APP_FIREBASE_STORAGE_BUCKET=your_storage_bucket
REACT_APP_FIREBASE_SENDER_ID=sender_id

React側の設定

Reactアプリケーションはcreate-react-appか何かでセッティングしておいてください。
必要なパッケージをインストールします。

$ npm install --save firebase react-router react-router-dom
($ yarn add firebase react-router react-router-dom)

Firebaseにログインするのと、余分ですがFirestoreに接続する設定は以下です。

/src/utils/firebase.js

import firebase from "firebase";

firebase.initializeApp({
  // Authentication infomation
  apiKey: process.env.REACT_APP_FIREBASE_KEY,
  authDomain: process.env.REACT_APP_FIREBASE_DOMAIN,
  databaseURL: process.env.REACT_APP_FIREBASE_DATABASE,
  projectId: process.env.REACT_APP_FIREBASE_PROJECT_ID,
  storageBucket: process.env.REACT_APP_FIREBASE_STORAGE_BUCKET,
  messagingSenderId: process.env.REACT_APP_FIREBASE_SENDER_ID
})

const auth = firebase.auth()
const db = firebase.firestore()

export {auth, db}

create-react-appでは.envファイルの中身をprocess.envで取れるようになっているらしいです。

Context作成

/src/contexts/Auth.js
import React, { createContext, useState, useEffect } from 'react'
import { auth } from '../utils/firebase'


export const AuthContext = createContext();

export const AuthProvider = ({children}) => {
	const [currentUser, setCurrentUser] = useState(null)
	
	const signup = async (email, password, history) => {
		try {
			await auth.createUserWithEmailAndPassword(email, password);
			history.push("/");
		}catch(error){
			alert(error);
		}
	}

	const signin = async (email, password, history) => {
		try{
			await auth.signInWithEmailAndPassword(email, password);
			history.push("/");
		}catch(error){
			alert(error);
		}
	}

	const signout = async () => {
		await auth.signOut()
	}
	
	useEffect(() => {
		auth.onAuthStateChanged(setCurrentUser);
	}, [])

	return (
		<AuthContext.Provider value={{currentUser, signup, signin, signout}}>
			{children}
		</AuthContext.Provider>
	)
}

こんな感じで認証系のContextができました。

Routerの設定

SignInとSignUpのページ以外はサインインしないと見れないようにしたいので、PrivateRouterを作ります。

/src/pages/PrivateRouter.js
import React, { useContext } from "react";
import { Route } from "react-router-dom";
import { AuthContext } from "../contexts/Auth";
import SignIn from "./SignIn";

const PrivateRouter = ({ component: RouteComponent, ...options}) => {
  const { currentUser } = useContext(AuthContext);
  const Component = currentUser ? RouteComponent: SignIn;

  return <Route {...options} component={Component} />;
};

export default PrivateRouter;

これで、currentUserがnullの場合はSignInに飛びます。
SignInページはあとで作ります。

次に、App.jsにこのPrivateRouterを使ってRoutingを設定していきます。

/src/App.js
import React from 'react';
import { BrowserRouter as Router, Route } from "react-router-dom";

import { AuthProvider } from "./contexts/Auth";
import PrivateRoute from "./pages/PrivateRouter";
import Home from "./pages/Home";
import SignIn from "./pages/SignIn";
import SignUp from "./pages/SignUp";

export default function App() {
  return (
    <AuthProvider>
      <Router>
        <div>
          <PrivateRoute exact path="/" component={Home} />
          <Route exact path="/signin" component={SignIn} />
          <Route exact path="/signup" component={SignUp} />
        </div>
      </Router>
    </AuthProvider>
  );
}

Homeは、認証後に表示したいページです。

サインイン、サインアップページ

簡単に作っていこうと思います。

/src/pages/SignIn.js
import React, { useContext } from "react";
import { withRouter } from "react-router";
import { AuthContext } from "../contexts/Auth";

const SignIn = ({ history }) => {
  const { signin } = useContext(AuthContext);
  const handleSubmit = event => {
    event.preventDefault();
    const { email, password } = event.target.elements;
    signin(email.value, password.value, history);
  };

  return (
    <div>
      <h1>Sign in</h1>
      <form onSubmit={handleSubmit}>
        <label>
          Email
          <input name="email" type="email" placeholder="Email" />
        </label>
        <label>
          Password
          <input name="password" type="password" placeholder="Password" />
        </label>
        <button type="submit">Sign in</button>
      </form>
    </div>
  );
};

export default withRouter(SignIn);
/src/pages/SignUp.js
import React, { useContext } from "react";
import { withRouter } from "react-router";
import { AuthContext } from "../contexts/Auth";

const SignUp = ({ history }) => {
  const { signup } = useContext(AuthContext);
  const handleSubmit = event => {
    event.preventDefault();
    const { email, password } = event.target.elements;
    signup(email.value, password.value, history);
  };

  return (
    <div>
      <h1>Sign up</h1>
      <form onSubmit={handleSubmit}>
        <label>
          Email
          <input name="email" type="email" placeholder="Email" />
        </label>
        <label>
          Password
          <input name="password" type="password" placeholder="Password" />
        </label>
        <button type="submit">Sign Up</button>
      </form>
    </div>
  );
};

export default withRouter(SignUp);

これで、signin,signup関数を使ってサインインとサインアップができるようになりました。
サインアウトは以下で済むので簡単ですね。

<button onClick={signout}>Sign out</button>

これで認証を実装することができました。

感想

今回は承認機能を実装してみましたがfirebaseを使うとかなり簡単にできたように思います。
このくらいだとreduxを使わず、ContextAPIを使うほうが良さそうですね。
これからバックエンドとの連携やtypescriptの導入なんかもやってみたいですね!

参考

【React】 Firebaseを使用して認証機能の実装
ReactHooks + Firebase(Authentication, Firestore)でTodoアプリ作る

17
21
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
21

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?