karhal / web3-connect
允许通过以太坊钱包在 symfony 应用中进行登录
Requires
- php: >=7.4
- ext-json: *
- doctrine/doctrine-bundle: ^2.7
- doctrine/orm: *
- firebase/php-jwt: ^6.0.0
- illuminate/support: ^10.0
- kornrunner/keccak: ^1.1
- simplito/elliptic-php: ^1.0
- symfony/cache: >=6.0
- symfony/dependency-injection: >=5.4
- symfony/event-dispatcher: >=5.4
- symfony/security-bundle: 6.4.*
- symfony/validator: 6.4.*
Requires (Dev)
- phpunit/phpunit: 10.0.17
- rector/rector: 0.15.22
- symfony/test-pack: *
- dev-main
- 0.1.2
- 0.1.1
- 0.1
- 0.0.4
- 0.0.3
- 0.0.2
- 0.0.1
- dev-renovate/phpunit-phpunit-11.x
- dev-renovate/phpunit-phpunit-10.x
- dev-renovate/rector-rector-1.x
- dev-renovate/major-symfony
- dev-fix/route
- dev-feature/stateless
- dev-feature/vendors_upgrade
- dev-renovate/rector-rector-0.x
- dev-renovate/major-illuminate
- dev-EIP4361_regex
This package is auto-updated.
Last update: 2024-09-19 13:55:44 UTC
README
Web3 钱包 Connect 包
描述
此 Symfony 包允许用户通过他们的以太坊钱包进行认证。为此,您只需要让他们用他们的钱包签名一条消息。
此包使用 EIP-4361,旨在与 spruceid/siwe 库一起工作
为什么?
您的钱包允许您通过您的以太坊账户连接到任何去中心化应用程序。这就像一个您可以在许多 dapp 上使用的登录凭证。此包旨在将此功能带给每个 Symfony 网站。
入门
安装
composer require karhal/web3-connect
<?php //config/bundles.php return [ //... , Karhal\Web3ConnectBundle\Web3ConnectBundle::class => ['all' => true], ];
配置
config/packages/web3_connect.yaml
wallet_connect: user_class: App\Entity\User jwt_secret: MySecretPhrase
config/packages/security.yaml
security: #... providers: #... web3_user_provider: entity: class: App\Entity\User property: walletAddress firewalls: #... web3: custom_authenticators: - Karhal\Web3ConnectBundle\Security\Web3Authenticator provider: web3_user_provider main: #...
config/routes.yaml
web3_link: resource: "@Web3ConnectBundle/config/routes.yaml"
通过实现 Web3UserInterface 更新表示用户的类的模型
//... use use Karhal\Web3ConnectBundle\Model\Web3UserInterface; //... class User implements Web3UserInterface { //... #[ORM\Column(type: 'string', nullable: true)] private ?string $walletAddress; public function getWalletAddress(): string { return $this->walletAddress; } public function setWalletAddress(string $wallet) { $this->walletAddress = $wallet; } }
然后更新您的存储
php bin/console doctrine:mig:diff php bin/console doctrine:mig:mig
现在您可以开始了
使用
此包提供了一个签名路由来生成要签名的消息。消息签名后,将其与签名的地址一起发送回来。
步骤 1:获取 nonce
在每次签名之前,从后端获取 nonce
const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, { credentials: 'include', mode: 'cors', headers: { 'Accept': 'application/json', }, });
步骤 2:生成消息
const message = await createSiweMessage( await signer.getAddress(), 'Sign in with Ethereum to the app.' );
步骤 3:发送带有签名的消息
const res = await fetch(`${BACKEND_ADDR}/web3_verify`, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ message, signature }), credentials: 'include', method: "POST", mode: 'cors', });
完整的示例(使用 spruceid/siwe-quickstart 示例)
import { ethers } from 'ethers'; import { SiweMessage } from 'siwe'; const domain = window.location.host; const origin = window.location.origin; const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); const BACKEND_ADDR = "http://127.0.0.1:8000"; async function createSiweMessage(address, statement) { const res = await fetch(`${BACKEND_ADDR}/web3_nonce`, { credentials: 'include', mode: 'cors', headers: { 'Accept': 'application/json', }, }); const message = new SiweMessage({ domain, address, statement, uri: origin, version: '1', chainId: '1', nonce: (await res.json()).nonce }); return message.prepareMessage(); } function connectWallet() { provider.send('eth_requestAccounts', []) .catch(() => console.log('user rejected request')); } async function signInWithEthereum() { const message = await createSiweMessage( await signer.getAddress(), 'Sign in with Ethereum to the app.' ); const signature = await signer.signMessage(message); const res = await fetch(`${BACKEND_ADDR}/web3_verify`, { headers: { 'Accept': 'application/json', 'Content-Type': 'application/json', }, body: JSON.stringify({ message, signature }), credentials: 'include', method: "POST", mode: 'cors', }); document.getElementById('infoUser').innerText = 'Welcome '+ (await res.json()).identifier; } const connectWalletBtn = document.getElementById('connectWalletBtn'); const siweBtn = document.getElementById('siweBtn'); connectWalletBtn.onclick = connectWallet; siweBtn.onclick = signInWithEthereum;
该包将验证签名的消息是否属于该地址。如果是,您的存储中将加载地址的所有者作为 JWT 令牌。
响应
{ "identifier": "foo@bar.com", "token": "eyJ0eXs[...]", "data": {} }
步骤 4:访问授权路由
现在,您可以通过在请求的头部添加带有刚刚生成的令牌值的 http_header
来向授权路由发出请求。
const res = await fetch(`${BACKEND_ADDR}/private_url`, { headers: { 'Accept': 'application/json', 'X-AUTH-WEB3TOKEN': 'eyJ0eXs[...]' }, });
步骤 5:自定义包响应
在返回响应之前,包将触发一个 DataInitializedEvent
事件,提供您可以填充以向前端提供一些额外信息的数组。
您可以通过监听此事件并调用其 setData
方法来添加任何想要的数据。
<?php namespace App\EventListener; use Karhal\Web3ConnectBundle\Event\DataInitializedEvent; class Web3LoginEventListener { public function onWeb3userDataInitialized(DataInitializedEvent $event) { $event->setData(['foo' => 'bar']); } }
响应
{ "identifier": "foo@bar.com", "token": "eyJ0eXs[...]", "data": { "foo": "bar" } }
资源
- PHP 中的快速椭圆曲线密码学
- Ethereum-PHP
- https://medium.com/fabric-ventures/what-is-web-3-0-why-it-matters-934eb07f3d2b
- https://medium.com/mycrypto/the-magic-of-digital-signatures-on-ethereum-98fe184dc9c7
- https://eips.ethereum.org/EIPS/eip-4361#message-field-descriptions
什么是以太坊钱包?
以太坊钱包是允许您与您的以太坊账户交互的应用程序。将其想象成一个没有银行的互联网银行应用程序。您的钱包允许您查看您的余额、发送交易并连接到应用程序。
“不再需要为不同网站记住唯一的密码。不再需要为不同服务创建唯一的电子邮件地址。不再需要担心您与之交互的网站从您那里窃取数据。在互联网上对您的账户进行纯粹的、自有的控制。除了在注册时生成的公钥之外,没有用户名、密码或其他识别信息。”
测试
vendor/bin/phpunit
许可
MIT 许可证 (MIT)。有关更多信息,请参阅 许可文件。