ethereum on rails (template): connect metamask to ruby on rails.
APACHE-2.0 License
Ethereum on Rails MVP: allow sign-up and log-in with Ethereum wallet (e.g., MetaMask browser extension).
✔️ If you are here to learn Ethereum-account authentication, welcome! Feel free to read the following article that is based on this code:
⚠️ If you are here to build Sign-in with Ethereum for production, you should use the SIWE libraries instead:
^3.0.0
^7.0.0
^17.4.0
pacman -S ruby rubygems sqlite nvm
nvm install stable
npm install --global npm yarn
gem install bundler rails
nvm use stable
bundle install
bin/rails webpacker:install
bin/rails db:migrate
bin/rails server
User
The user contains three attributes: username
, eth_address
, eth_nonce
.
UUID
that has to be signed for authentiation.In this MVP, all three fields are mandatory and have to be unique.
Users{#new,#create}
The users controller is solely used for creating new users.
SecureRandom.uuid
.eth_address
from the sign-up view (see below).eth_address
is a valid Ethereum address.Users#new
The Users#new
view is the sign-up page to create a new account.
Connect
button to establish a connection with the Ethereum provider.The JavaScript pack users_new.js
contains the frontend logic to establish a connection with an Ethereum wallet.
method: 'eth_requestAccounts'
eth_address
to the form and submits it.Sessions{#new,#create,#destroy}
The sessions controller manages the user authentication (login/logout).
eth_address
provided by Ethereum wallet.It also handles destroying sessions to log users out.
The JavaScript pack sessions_new.js
contains the frontend logic to authenticate a user with an Ethereum account.
method: 'eth_requestAccounts'
fetch("/api/v1/users/" + account)
method: 'personal_sign', params: [ message, account ]
/api/v1/users{#index,#show}
To prevent signature spoofing, the user needs to sign a specific piece of information we can verify in the backend rather than a random message. The User
model contains an eth_nonce
field that gets filled with a random UUID on first sign-up and gets rotated on every successful login.
The #index
controller explicitly returns nil
to prevent accessing the full set of users from the database.
/api/v1/users
, returns null
The #show
controller gets a user by eth_address
from the database and returns the eth_nonce
or nil
if it does not exist.
/api/v1/users/${eth_account}
eth_account
parameter is a valid Ethereum address to filter out seemingly random requests.eth_account
key.eth_nonce
as JSON.null
if it fails in any step above.The Ethereum-on-Rails template was written by @q9f can be found and used on Github directly: github/q9f/ethereum-on-rails
This Rails application template implements the logic described by Amaury Martiny in One-click Login with Blockchain: A MetaMask Tutorial - brilliant, though slightly outdated, resource! Thanks for that.