В этой статье мы создадим логин пользователя, используя Next.js с перехватчиками React. И мы защитим наше приложение с помощью функции аутентификации Firebase, которая позволяет только авторизованным пользователям получать доступ к частной странице.

Список моментов, на которых мы остановимся в этой статье:

  • Настройка Next.js
  • Компонент React
  • Реагировать на крючок
  • Аутентификация Firebase
  • Сторонняя аутентификация с Google

Примечание. Для этого в нашей системе должны быть установлены Node.js и npm

Настройка Next.js

При создании проекта Next.js нам необходимо установить модуль create-next-app, который обеспечивает начальную настройку и настройку по умолчанию. Установите create-next-app командой:

npm install -g create-next-app

После завершения установки запустите проект Next.js в вашем локальном каталоге, где нам нужно создать проект, с помощью команды:

npx create-next-app next-login-firebase

После завершения установки переходим в нашу созданную папку:

cd next-login-firebase

Теперь мы закончили настройку нашего проекта Next.js.

Следующим шагом будет установка пакета Firebase и react-firebaseui.

npm i firebase react-firebaseui --save

Конфигурация Firebase для аутентификации

Firebase помогает нам с безопасным входом в систему, предоставляя методы мульти-аутентификации, такие как адрес электронной почты / пароль, Google, Facebook, Twitter и т. Д.

Перейдите на https://firebase.google.com/ и войдите со своими учетными данными.

После успешного входа в консоль Firebase мы создадим наш проект, нажав кнопку «Добавить проект», заполните форму имени проекта и следуйте инструкциям мастера:

Чтобы интегрировать наш проект Firebase в наш проект Next.js, перейдите в настройки проекта и найдите «Установка и конфигурация SDK», выберите радио «Конфигурация». Нам нужно будет скопировать фрагмент, который нужно добавить в код нашего проекта.

После создания проекта нажмите «Аутентификация» в левой части. Мы включим аутентификацию провайдера с помощью электронной почты / пароля и Google:

Написать код

В корневой папке создайте новый файл config.js с приведенным ниже кодом и сохраните его.

import firebase from 'firebase/app';
import 'firebase/auth';
const firebaseConfig = {
apiKey: "AIzaSyAXXXXXXX",
authDomain: "next-login-firebase.firebaseapp.com",
projectId: "next-login-firebase",
storageBucket: "next-login-firebase.appspot.com",
messagingSenderId: "86849XXXXX",
appId: "1:868XXXXXXXX:web:e3c06XXXXXXXXXXXX"
};
export default function initFirebase() {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseConfig);
}
}
view raw config.js hosted with ❤ by GitHub

Откройте файл pages / index.js и отредактируйте с помощью приведенного ниже кода.

const Home = () => {
return (
<div >
<div>Public</div>
<div><a href="/private">Go to Private</a></div>
</div>
)
}
export default Home;
view raw index.js hosted with ❤ by GitHub

Для следующего шага установите пакет «js-cookie» командой:

npm i js-cookie

Создайте новый файл auth / userCookie.js, напишите следующий код:

import cookies from 'js-cookie';
export const getUserFromCookie = () => {
const cookie = cookies.get('auth');
if (!cookie) {
return;
}
return JSON.parse(cookie);
};
export const setUserCookie = user => {
cookies.set('auth', user, {
expires: 1 / 24
});
};
export const removeUserCookie = () => cookies.remove('auth');
view raw userCookie.js hosted with ❤ by GitHub

Затем мы должны создать auth / useUser.js для обработки состояния пользователя, напишите следующий код:

import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import firebase from 'firebase/app';
import 'firebase/auth';
import initFirebase from '../config';
import {
removeUserCookie,
setUserCookie,
getUserFromCookie
} from './userCookie';
initFirebase();
export const mapUserData = async user => {
const { uid, email } = user;
const token = await user.getIdToken(true);
return {
id: uid,
email,
token
};
};
const useUser = () => {
const [user, setUser] = useState();
const router = useRouter();
const logout = async () => {
return firebase
.auth()
.signOut()
.then(() => {
router.push('/');
})
.catch(e => {
console.error(e);
});
};
useEffect(() => {
const cancelAuthListener = firebase
.auth()
.onIdTokenChanged(async userToken => {
if (userToken) {
const userData = await mapUserData(userToken);
setUserCookie(userData);
setUser(userData);
} else {
removeUserCookie();
setUser();
}
});
const userFromCookie = getUserFromCookie();
if (!userFromCookie) {
return;
}
setUser(userFromCookie);
return () => cancelAuthListener;
}, []);
return { user, logout };
};
export { useUser };
view raw useUser.js hosted with ❤ by GitHub

Создайте файл с именем «auth / withAuth.js» для обработки изменения статуса авторизации и перенаправления на подписывающие страницы:

import React, { useEffect } from 'react';
import router from 'next/router';
import firebase from 'firebase/app';
import 'firebase/auth';
import initFirebase from '../config';
initFirebase();
const auth = firebase.auth();
const withAuth = Component => props => {
useEffect(() => {
auth.onAuthStateChanged(authUser => {
if (!authUser) {
router.push('/signin');
}
});
}, []);
return (
<div>
<Component {...props} />
</div>
)
};
export default withAuth;
view raw withAuth.js hosted with ❤ by GitHub

Создайте новую частную страницу с именем «pages / private.js», эта страница будет отображать электронную почту и кнопку выхода, если пользователь входит в систему.

import withAuth from '../auth/withAuth';
import { useUser } from '../auth/useUser';
const Private = () => {
const { user, logout } = useUser();
return (
<div >
<div>Private</div>
{
user?.email &&
<div>
<div>Email: {user.email}</div>
<button onClick={() => logout()}>Logout</button>
</div>
}
</div>
)
}
export default withAuth(Private);
view raw private.js hosted with ❤ by GitHub

На последнем этапе создайте новый файл «pages / signin.js» для визуализации канала входа. Это пример использования «react-firebaseui».

import StyledFirebaseAuth from 'react-firebaseui/StyledFirebaseAuth';
import firebase from 'firebase/app';
import 'firebase/auth';
import initFirebase from '../config';
import { setUserCookie } from '../auth/userCookie';
import { mapUserData } from '../auth/useUser';
initFirebase();
const firebaseAuthConfig = ({ signInSuccessUrl }) => ({
signInFlow: 'popup',
signInOptions: [
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
requireDisplayName: false
},
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
],
signInSuccessUrl,
credentialHelper: 'none',
callbacks: {
signInSuccessWithAuthResult: async ({ user }, redirectUrl) => {
const userData = await mapUserData(user);
setUserCookie(userData);
}
}
});
const FirebaseAuth = () => {
const signInSuccessUrl = "/private"
return (
<div>
<StyledFirebaseAuth
uiConfig={firebaseAuthConfig({ signInSuccessUrl })}
firebaseAuth={firebase.auth()}
signInSuccessUrl={signInSuccessUrl}
/>
</div>
);
};
export default FirebaseAuth;
view raw signing.js hosted with ❤ by GitHub

Наш код:



Больше контента на plainenglish.io