Обработка пользовательских данных, вероятно, является одной из самых сложных частей для любого приложения (веб или нет). Существует так много мест, где что-то может пойти не так, что становится действительно сложно гарантировать, что ваше приложение действительно безопасно.
Даже большие компании могут стать жертвой небезопасной системы аутентификации, ведущей к неловким вещам, таким как утечка данных, что, в свою очередь, приводит к другим неприятным вещам, таким как судебные иски, которых, я уверен, вы бы хотели избежать.
Вот почему важно следовать последним передовым методам при разработке системы аутентификации для своего веб-приложения. Еще лучше, вы можете попросить кого-нибудь более опытного сделать это за вас, пока вы сосредоточитесь на основных функциях вашего приложения.
Введите Google’s Firebase. Firebase в данном случае - это кто-то более опытный, который будет обрабатывать нашу аутентификацию за нас.
С Firebase вы можете использовать опыт некоторых из самых умных умов в разработке программного обеспечения для создания системы аутентификации, которая прошла испытания в течение многих лет и проверена профессионалами отрасли.
Firebase на самом деле представляет собой набор решений для типичных проблем, с которыми сталкиваются разработчики при создании мобильных приложений, но в целях этой статьи мы сосредоточимся только на аутентификации.
Что вам нужно делать
- Аккаунт Google Firebase
- Настройка локальной разработки
- Базовые знания React и React Router
- Ведро кофе, а почему бы и нет?
ПРЕДУПРЕЖДЕНИЕ: в этой статье мы будем использовать небольшое количество React Hook, поэтому вам следует освежить свои навыки работы с Hooks здесь и здесь.
Чтобы получить учетную запись Firebase, посетите firebase.google.com и нажмите Начать. Обратите внимание, что для этого вам необходимо войти в свою учетную запись Google.
Если все пойдет хорошо, вы будете перенаправлены на консоль. Здесь вы можете создавать новые проекты и управлять существующими, поэтому давайте создадим новый проект. После входа в консоль Firebase вы увидите большую синюю кнопку с текстом «Добавить проект». Это тот, на который вы хотите нажать.
Нажмите на нее и заполните всплывающую форму. Дайте вашему проекту легко узнаваемое имя и продолжайте. Я назову свой «Бензин», и нет, вы не можете спросить почему.
После того, как вы заполните и отправите форму, вы будете перенаправлены в представление проекта. Здесь вы можете добавлять приложения в этот проект (в моем случае «Бензин»). У вас есть возможность добавлять различные типы приложений, но для этого урока мы выберем веб-приложение.
Нажав на опцию веб-приложения, вы получите набор кода, который вы должны добавить в свое веб-приложение. Это просто ссылка на CDN Firebase и объект конфигурации для Firebase. Выглядит это примерно так:
Вы хотите скопировать объект конфигурации и сохранить его в легкодоступном месте, потому что он нам очень скоро понадобится.
Еще одна вещь, которую нужно решить, прежде чем мы начнем. Мы хотим включить аутентификацию с использованием электронной почты и пароля в нашей консоли Firebase.
На левой боковой панели страницы обзора проекта нажмите «Разработка», и вы должны увидеть, что появятся некоторые параметры. Нажмите «Аутентификация», и вы должны увидеть эту страницу:
Щелкните «Метод входа», и вы должны увидеть несколько методов, которые можно использовать для аутентификации пользователей. Мы начнем с малого и пока просто включим «Электронная почта / Пароль».
Хорошо! Давайте начнем!
Что будем строить
Чтобы вы освоили основы Firebase, мы создадим простое приложение React.js без лишних наворотов, отвлекающих вас.
Наше приложение будет простым веб-приложением с домашней страницей, двумя формами для регистрации и входа и страницей, доступной только авторизованным пользователям.
Настраивать
Весь код, написанный в этой статье, можно найти здесь = › Repo .
Клонируйте это репо, и у вас будет все необходимое, чтобы следовать этой статье. После клонирования репозитория создайте новый файл .env
в корне папки проекта.
Помните те учетные данные, которые Google дал нам, когда мы создавали наш проект? Они нам сейчас понадобятся. Обновите файл .env
, чтобы он выглядел точно так:
FIREBASE_API_KEY = <replace_with_yours> FIREBASE_AUTH_DOMAIN = <replace_with_yours> FIREBASE_DATABASE_URL = <replace_with_yours> FIREBASE_PROJECT_ID = <replace_with_yours> FIREBASE_STORAGE_BUCKET = <replace_with_yours> FIREBASE_MESSAGING_SENDER_ID = <replace_with_yours>
По завершении запустите npm i
, а после установки всех пакетов запустите npm start
. Смотри, мама, нет Webpack!
Вы должны увидеть, как эта очень впечатляющая страница открывается в новой вкладке:
Если вы попытались щелкнуть ссылку «VIP-раздел», вы заметите, что всплывает предупреждение о том, что вы можете получить доступ к этой странице только после входа в систему. Мы скоро узнаем, как это работает, но начнем с сначала основы.
Как это было построено?
Если вы еще не клонировали репозиторий проекта, сделайте это сейчас, чтобы вы могли следить за кодом. Я сосредоточусь только на тех частях приложения, которые используют Firebase, чтобы это не превратилось в очередное руководство по React. Видит Бог, с нас этого достаточно.
Откройте src/utilities/firebase.js
и давайте посмотрим, что делает этот файл.
import * as firebase from 'firebase/app'; import 'firebase/auth'; import dotenv from 'dotenv'; dotenv.config(); const fireBaseConfig = { apiKey: process.env.FIREBASE_API_KEY, authDomain: process.env.FIREBASE_AUTH_DOMAIN, databaseURL: process.env.FIREBASE_DATABASE_URL, projectId: process.env.FIREBASE_PROJECT_ID, storageBucket: process.env.FIREBASE_STORAGE_BUCKET, messagingSenderId: process.env.FIREBASE_MESSAGING_SENDER_ID, }; export default firebase.initializeApp(fireBaseConfig);
Вверху мы импортируем пакеты, необходимые для правильной работы Firebase. Опять же, dotenv
нужен только для того, чтобы помочь нам прочитать наш .env
файл, поэтому не сосредотачивайтесь на этой части.
Обратите внимание, что мы создаем fireBaseConfig
объект, необходимый для правильной работы Firebase. В конце этого файла мы просто инициализируем Firebase с помощью нашего объекта конфигурации и экспортируем его за один раз. Пока что все довольно просто.
Теперь у нас настроена и готова к работе Firebase. Это буквально так просто. Без пуха.
Регистрация новых пользователей
Давайте рассмотрим соответствующую часть src/components/Signup.jsx
и то, как она работает.
... omitted for brevity ... const [formData, setFormData] = useState({ email: '', password: '', }); const handleInputChange = event => setFormData({ ...formData, [event.target.name]: event.target.value, }); const onFormSubmit = async (event) => { event.preventDefault(); await fBase .auth() .createUserWithEmailAndPassword(formData.email, formData.password); return <Redirect to="/protected" />; }; ... omitted for brevity ...
Это соответствующая часть компонента регистрации, о которой стоит поговорить. Просматривая этот код, вы заметите, что мы используем fBase
(это экземпляр Firebase, который мы инициализировали в firebase.js
) только один раз в функции onFormSubmit
.
Что там вообще происходит? Так как мы используем Firebase для аутентификации, в нашем распоряжении есть несколько методов (полный список здесь).
В сторону: Один из аспектов Firebase, который мне действительно нравится, - это очень информативные имена всех методов. К этому нужно стремиться в любом проекте, над которым вы работаете.
Нам доступны различные методы для создания новых пользователей, но для этой статьи мы выберем метко названный createUserWithEmailAndPassword()
, который делает именно то, что написано на коробке.
Таким образом, этот метод принимает два аргумента: адрес электронной почты и пароль нового пользователя. Затем он создает для нас нового пользователя и сохраняет этого пользователя в бесплатной базе данных, предоставленной нам Firebase.
Поскольку вызов этого метода приведет к обещанию, мы должны дождаться его, и когда он завершится успешно, мы собираемся перенаправить пользователя на защищенную страницу.
Попробуйте сами. Запустите сервер, запустив npm start
, перейдите на страницу регистрации, создайте нового фиктивного пользователя, вернитесь в консоль Firebase и обновите страницу. Вы должны увидеть нового пользователя вот так:
На самом деле создать нового пользователя с помощью Firebase очень просто. Я не собираюсь включать здесь обработку ошибок, потому что в этом случае статья получится довольно длинной. Но просто знайте, что Firebase выявляет ошибки, такие как слабые пароли и недействительные электронные письма, даже если вы не настраивали его вручную.
Попробуйте сами и убедитесь. Вернитесь на страницу регистрации, откройте консоль браузера, заполните форму регистрации и используйте ненадежный пароль (попробуйте «слабый») и нажмите «Отправить». Вы заметите, что запрос не будет выполнен, и в консоли появится сообщение об ошибке, указывающее на то, что ваш пароль ненадежен.
Тем не менее, вы все равно хотите настроить проверку пароля, потому что Firebase разрешает бессмысленные пароли, такие как «пароль».
Бонусные баллы, если вы можете настроить обработку ошибок с помощью описательных сообщений для пользователя и анимации загрузчика, когда запрос ожидает обработки.
Авторизоваться
Вы видели, как легко было создать нового пользователя с помощью Firebase. Что ж, войти в систему этого нового пользователя так же просто. Давайте откроем src/components/Login.jsx
и посмотрим, как это делается.
... omitted for brevity ... const [formData, setFormData] = useState({ email: '', password: '', }); const handleInputChange = event => setFormData({ ...formData, [event.target.name]: event.target.value, }); const onFormSubmit = async (event) => { event.preventDefault(); await fBase .auth() .signInWithEmailAndPassword(formData.email, formData.password); return <Redirect to="/protected" />; }; ... omitted for brevity ...
Соответствующие части этого компонента почти идентичны компоненту «Регистрация». Есть только одно отличие.
Там, где мы использовали fBase.auth().createUserWithEmailAndPassword
для регистрации пользователя, мы используем fBase.auth().signInWithEmailAndPassword
для входа пользователя в систему. Серьезно, это единственная разница.
Опять же, проверка уже выполняется за нас в фоновом режиме. Попробуйте войти в систему только что созданного пользователя, но используйте неверный пароль и проверьте консоль. Вы должны увидеть консольную ошибку, сообщающую, что пароль недействителен.
Вы можете настроить обработку ошибок и отображать эту ошибку пользователю менее чем за 5 минут. Все проблемы, связанные с безопасным хранением паролей, выпуском токенов, принятием решения о том, как хранить токены и т. Д., Были решены за нас.
Проверка, авторизован ли пользователь
Мы увидели, как легко создать нового пользователя и как выполнять вход в систему. Как мы можем проверить, вошел ли пользователь в систему в настоящее время или нет? Вы, наверное, уже догадались: вызовите fBase.auth()
метод. Давайте откроем src/Root.jsx
и посмотрим, как это делается.
... omitted for brevity ... constructor(props) { super(props); this.state = { user: null }; this.history = createBrowserHistory(); } componentDidMount() { fBase.auth().onAuthStateChanged((auth) => { if (auth) { this.setState({ user: auth.providerData[0] }); } }); } ... omitted for brevity ...
Итак, это корневой компонент, через который отображаются все остальные компоненты. Когда этот компонент монтируется, мы собираемся вызвать еще один fBase.auth()
метод, который поможет нам проверить, вошел ли пользователь в систему.
Если пользователь в настоящее время вошел в систему, auth
будет содержать сведения об этом пользователе, такие как отображаемое имя, адрес электронной почты, метод аутентификации и т. Д. Если нет, auth
будет null
.
Это так просто. Вам не нужно вручную проверять sessionStorage, localStorage или даже возиться с файлами cookie (фу!), Чтобы убедиться, что пользователь в настоящее время вошел в систему.
Теперь, как мы сделали так, чтобы VIP-раздел отображался только тогда, когда пользователь вошел в систему? Итак, поскольку теперь мы можем проверить, вошел ли пользователь в систему и получить сведения об этом пользователе, я решил использовать метод рендеринга для условного рендеринга защищенного компонента. Подробнее см. Здесь.
Основная суть в том, что мы проверяем this.state.user !== null
, и если это так, то мы знаем, что пользователь в настоящее время вошел в систему, и мы можем разрешить пользователю доступ к странице. Вот код для этого:
... omitted for brevity ... function PrivateRoute({ component: Component, user, ...rest }) { if (!user) { window.alert('You must be signed in to access that page'); return <Redirect to="/" />; } return (<Route {...rest} render={props => <Component {...props} />} />); } ... this is where I export this function ...
И вот как мы используем его в компоненте Router Switch в src/Root.jsx
:
<PrivateRoute path="/protected" component={Protected} user={user} />
Есть и другие (и я уверен, что намного лучше) способы сделать это, но вы уже должны уловить суть. Вызовите fBase.auth().onAuthStateChanged
, и если он вернет что-либо, кроме null
, значит, пользователь в настоящее время вошел в систему. Легко.
Выйти
Вы уже должны знать, что я собираюсь вам показать, ха-ха. Чтобы выйти из системы, все, что вам нужно сделать, это позвонить fBase.auth().signOut()
в любое место, где вы хотите, и текущий вошедший в систему пользователь автоматически выйдет из системы.
Выводы
Итак, я хотел кое-что прояснить, прежде чем закончить эту статью (кстати, если вы дочитали ее до конца, вы классные, и я люблю вас). Вам НЕ нужно использовать Firebase, чтобы получить безопасную систему аутентификации.
Вы можете создать достаточно безопасную систему аутентификации самостоятельно, если будете следовать текущим (они постоянно меняются) передовым методам аутентификации.
Причина, по которой я рекомендую людям использовать Firebase, заключается в том, что она тщательно проверялась на протяжении многих лет, и вероятность взлома данных ваших пользователей гораздо меньше, чем если бы вы работали в одиночку. Тебе действительно не нужны эти судебные процессы.
Эта статья ЕЩЕ РАЗ даже коснулась поверхности возможностей Firebase. Я имею в виду ЕЩЕ РАЗ. Если вы действительно хотите (и я имею в виду действительно) использовать все возможности Firebase, вам следует ознакомиться с курсами Джеффа Делани по Firebase.
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: я не знаю Джеффа лично и не получаю комиссионных за рекомендации его курсов. Я рекомендую его только потому, что он умеет объяснять вещи, которые делают все намного проще. Иди проверь его. Шутки в сторону.
Если у вас есть какие-либо вопросы, у вас есть лучший подход ко всему этому, вы обнаружили ошибки в моем уродливом коде или просто хотите поздороваться, дайте мне знать, оставив комментарий. Написание того стоит именно из-за ваших ответов.
Эта статья изначально была опубликована здесь.
📝 Прочтите этот рассказ позже в Журнале.
👩💻 Просыпайтесь каждое воскресное утро и слушайте самые интересные истории недели в области технологий, которые ждут вас в вашем почтовом ящике. Прочтите информационный бюллетень« Примечательно в технологиях .