Не секрет, что логин Ethereum скоро станет пользовательским стандартом, а пароли больше не будут необходимы. Тем не менее, Dapp Development все еще довольно молодое направление, и многие стандарты для их развития все еще устанавливаются.
Теперь все разработчики продолжают писать DAPPS со старыми практиками, инстинктивно используя тот же JWT для аутентификации. Я предлагаю немного другой подход.
Я сам начал разрабатывать dapps, используя jwt. Из первого проекта я чувствовал, что аутентификация всегда становится сложной, и в процессе должно быть что-то избыточное. После нескольких проектов я понял, что сам JWT избыточно. Позвольте мне объяснить, почему.
Эта диаграмма показывает, как я сделал аутентификацию на моих первых нескольких проектах. Здесь схема почти полностью повторяет стандартную процедуру с JWT, единственное, что вместо логина и пароля пользователь отправляет подпись.
Почему нам нужно получить JWT? Ведь даже без него вы можете надежно идентифицировать пользователя, взяв адрес от его подписи.
Вот как это упростить:
Пользователь по-прежнему генерирует подпись, но уже со скоростью истекает внутри, так что если злоумышленник получает подпись, он не будет полезен долго (такой же, как и с JWT). Кроме того, подпись находится в стандартном заголовке авторизации и обрабатывается на сервере, взяв адрес пользователя и поиск пользователя в базе данных. Это все. И вам не нужно постоянно обновлять ключи шифрования для JWT на сервере, поэтому в общем, много ответственности падает с сервера.
Чтобы упростить этот поток еще больше, я сделал модуль Web3-Token. Чтобы установить его, используйте команду:
$ npm я web3-токен
Этот модуль можно использовать как на сервере, так и на клиенте. Давайте посмотрим на пример, начиная с набора клиента.
import Web3Token from 'web3-token';
// Connection to MetaMask wallet (you can actually use any wallet)
// you can even use ethersjs instead of web3
const web3 = new Web3(ethereum);
await ethereum.enable();
// getting address from which we will sign message
const address = (await web3.eth.getAccounts())[0];
// generating a token with 1 day of expiration time
const token = await Web3Token.sign(msg => web3.eth.personal.sign(msg, address), '1d');
// attaching token to axios authorization header
axios.post('/registration', { name: 'Adam' }, {
headers: {
'Authorization': token,
}
})
// checking how it finds me in backend's database
axios.get('/me', {
headers: {
'Authorization': token,
}
})
После звонка метода .sign вы увидите что-то подобное этому (если вы используете Metamask).
Как видите, сообщение совершенно прозрачно для пользователя, поскольку они должны увидеть, что они подписывают. Таким образом, вместо того, чтобы использовать структуру JSON для лучшей читабельности, я решил использовать ту же структуру, что и для заголовков HTTP.
В теле сообщения мы видим версию токена и самой даты истечения.
Далее, вот что бэкэнда (Node.js) делает с этим токеном:
const Web3Token = require('web3-token');
// getting a token from authorization header
const token = req.headers['Authorization']
const { address, body } = await Web3Token.verify(token);
// now you can find that user by his address
// tip: better to do it case insensitive
req.user = await User.findOne({ address });
Это довольно просто, только одна строка, а модуль берет во все криптографии. Мы волшебно получаем адрес пользователя из подписи и найду их в базе данных, используя этот адрес. Тогда, например, вы можете предоставить этому пользователю NFT по его адресу.
Результатом является очень удобный метод аутентификации пользователей без гражданства, идеально подходит для гибридных Dapps. Единственный недостаток в том, что трудно тестировать в Postman 😀
Я бы очень хотел что-то вроде стандарта, чтобы выйти из этого, но до тех пор я открыт для критики (или, возможно, вопросы/предложения)
Web3 находится всего за углом.
Оригинал: “https://dev.to/bylde/you-dont-need-jwt-anymore-2mcd”