В этом блоге мы рассмотрим, как мы можем аутентифицировать пользователя с помощью JSON Web Token, также известного как JWT. JWT — один из лучших стандартов для реализации системы аутентификации в вашем приложении стека MERN.
JSON Web Token (JWT) — это открытый стандарт (RFC 7519), определяющий компактный и автономный способ безопасной передачи информации между сторонами в виде объекта JSON. Эту информацию можно проверить и ей можно доверять, поскольку она имеет цифровую подпись. JWT можно подписать с помощью секрета (с помощью алгоритма HMAC) или пары открытого/закрытого ключей с использованием RSA или ECDSA.
Когда нам следует использовать JWT?
- Авторизация. Это наиболее распространенный сценарий использования JWT. После входа пользователя в систему каждый последующий запрос будет включать JWT, что позволяет пользователю получать доступ к маршрутам, службам и ресурсам, разрешенным с помощью этого токена. Единый вход — это функция, которая в настоящее время широко использует JWT из-за ее небольших накладных расходов и возможности легкого использования в разных доменах.
- Обмен информацией. Веб-токены JSON – это хороший способ безопасной передачи информации между сторонами.
Какова структура веб-токена JSON?
В своей компактной форме веб-токены JSON состоят из трех частей, разделенных точками (.), а именно:
- Заголовок
- Полезная нагрузка
- Подпись
Таким образом, JWT обычно выглядит следующим образом.
Ххххх.yyyyy.zzzzz
Поскольку JWT могут быть подписаны, например, с использованием пар открытого и закрытого ключей, вы можете быть уверены, что отправители являются теми, кем они себя называют. Кроме того, поскольку подпись рассчитывается с использованием заголовка и полезных данных, вы также можете убедиться, что контент не был подделан.
Серверная реализация:
Итак, ниже я поделился некоторыми фрагментами кода с некоторыми пояснениями. Ниже этих фрагментов кода мы проверим, не существует ли зарегистрированный пользователь в базе данных, затем он зашифрует пароль для хранения в базе данных и создаст пользователя. После создания пользователя он создаст токен JWT, используя идентификатор созданного пользователя и имя пользователя. Вы также можете использовать любой тип вводимых данных, например адрес электронной почты или номер телефона. Но я предлагаю также каждый раз включать идентификатор пользователя, чтобы сохранить уникальность токена.
- Создание JWT
jwt.sign({ id: response.user_id, name: response.user_name }, config.get("jwtSecret"), { expiresIn: 86400 }, (err, token) => { if (err) throw err; res.status(200).json({ expiresIn: 1 d, data: response, token: token, }); } );
Итак, как я упоминал ранее, токен JWT принимает 3 параметра. Первый параметр — это метод «sign», который принимает информацию, которую необходимо поместить в полезную нагрузку, которая преобразуется в токен JWT.
Второй параметр — это секретный ключ, используемый для создания дайджеста.
Третий параметр — это представление опции. Итак, в этом примере я установил срок действия токена в секундах.
2. Проверьте JWT с помощью промежуточного программного обеспечения:
const jwt = require("jsonwebtoken"); const config = require("config"); module.exports = function(req, res, next) { const token = req.header("Authorization"); if (!token) { return res.status(401).json({ msg: "Authorization denied", }); } try { const decoded = jwt.verify(token, config.get("jwtSecret")); req.user = decoded; next(); j } catch (err) { res.status(401).json({ msg: "invalid token", }); } };
В приведенном выше примере я реализовал промежуточное программное обеспечение Express.js, которое проверяет наличие токена и проверяет переданный нами токен.
Вы можете сослаться на приведенный выше пример как на базовую реализацию промежуточного программного обеспечения, которое ожидает, что JWT будет передан в заголовках HTTP-запроса, чтобы проверить, есть ли у него необходимые данные или нет.
В результате лучших практик проверки токена мы отправляем коды состояния 401 (неавторизованный), если токен недействителен или срок его действия истек, и 400 (неверный запрос), если токен отсутствует в заголовках.
Реализация на стороне клиента:
Итак, как упоминалось в заголовке выше, мы рассмотрим весь стек технологий, необходимый для реализации этой функциональности. На стороне клиента мы создадим приложение реагирования, которое будет взаимодействовать с серверной частью, которую мы создали выше.
- Создайте реагирующее приложение:
npx create-react-app blogapp-fe cd blogapp-fe npm start
Итак, если вы новичок в React.js, приведенные выше команды создадут приложение React с именем blogapp-fe с небольшим стандартным кодом и запустят сервер.
2. Создайте страницы аутентификации:
Как только ваш сервер заработает, создайте базовые страницы аутентификации для регистрации и входа. И при нажатии кнопки мы вызовем соответствующие API.
Здесь у меня есть общий пример базового компонента регистрации, где я добавил форму с некоторыми полями (имя, адрес электронной почты и пароль) и сделал макет отправки, чтобы продемонстрировать аутентификацию со стороны внешнего интерфейса.
import React, { useState } from 'react'; const SignupComponent = () => { const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = async (e) => { e.preventDefault(); // Create a user object with the form data const user = { name, email, password }; try { // Make a POST request to the API endpoint const response = await fetch('http://localhost:8080/signup', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(user) }); // Check if the request was successful if (response.ok) { const data = await response.json(); console.log('Signup successful:', data); // Reset form fields setName(''); setEmail(''); setPassword(''); } else { console.log('Signup failed:', response.status); } } catch (error) { console.log('An error occurred:', error); } }; return ( < form onSubmit = { handleSubmit } > < label > Name: < input type = "text" value = { name } onChange = { (e) => setName(e.target.value) } /> < /label> < br / > < label > Email: < input type = "email" value = { email } onChange = { (e) => setEmail(e.target.value) } /> < /label> < br / > < label > Password: < input type = "password" value = { password } onChange = { (e) => setPassword(e.target.value) } /> < /label> < br / > < button type = "submit" > Sign Up < /button> < /form> ); }; export default SignupComponent;
Вызовы API после регистрации будут выполняться указанным выше компонентом в нашу серверную часть, которая будет возвращать данные пользователя вместе с идентификатором и токеном доступа JWT, которые мы будем использовать для аутентификации пользователей и аутентификации запросов API, о которых я расскажу ниже в этом блоге.
Вы можете сохранить токен доступа к ответу в своем состоянии Redux, контексте или локальном хранилище браузера, чтобы получить к нему доступ из любого компонента.
Теперь в приведенном ниже фрагменте я сделал фиктивный вызов API get, который аутентифицируется с использованием токена доступа, который передается внутри заголовков запроса в качестве авторизации. И если токен действителен, он даст ответ с кодом состояния 200.
И если он недействителен или не пройден, наше промежуточное программное обеспечение аутентификации выдаст ошибку 401 с сообщением об ошибке недействительного токена.
Пример на стороне сервера:
app.get('/data', auth, (req, res) => { const data = { message: 'Data fetched successfully' }; res.json(data); });
Здесь auth — это наше промежуточное программное обеспечение, которое необходимо импортировать.
Пример на стороне клиента:
const fetchData = async () => { try { const response = await fetch('http://localhost:8080/data', { method: 'GET', headers: { 'Content-Type': 'application/json', 'Authorization': 'Bearer YOUR_AUTH_TOKEN' // Replace YOUR_AUTH_TOKEN with token } }); if (response.ok) { const data = await response.json(); console.log('Data fetched successfully:', data); } else { console.log('Failed to fetch data:', response.status); } } catch (error) { console.log('An error occurred:', error); } };
Заключение:
Итак, используя все эти примеры, вы можете легко реализовать приложение MERN со всей необходимой аутентификацией. Веб-токен JSON хорошо поддерживается и прост в использовании. На их официальном сайте вы можете найти библиотеки и инструменты для использования практически на любом языке — от Nodejs до Java и от .Net до Python.