【前言】
大家安安,今天的主題經過 MetaMask 強大的功能之後其實是可以省略的。開玩笑的,反正不管怎樣我都要把這個系統做到最好!接下來要說的是後端架設、基本資料結構的宣告與初始化。今天的內容大部份都參考來自 Amaury Martiny 的 One-click Login with Blockchain: A MetaMask Tutorial!
【Back-End 使用】
在這邊我是用 Node.js, Express, and SQLite 來做為後端架設,下載以及相關學習的部分就跳過否則太冗長而且有些偏離主題了,大家可以去參考別的文章,他們有很詳細又不錯的內容!
Docker 教學課程-第8部分:使用 Docker Compose
docker-compose.yml
的內容。這將會把後端架設在 localhost:8000
,以及把前端架設在 localhost:3000
。
version: '3.6'
services:
backend:
build:
context: ./backend
ports:
- '8000:8000'
frontend:
build:
context: ./src
ports:
- '3000:3000'
depends_on:
- backend
Dockerfile
的內容。
FROM node:12
COPY . /app
RUN cd /app && yarn install
WORKDIR /app
EXPOSE 8000/tcp
CMD yarn start
在 powershell
中執行以下命令,即可開始架設前後端。
docker-compose up -d
【Sequelize Init & Model】
首先先宣告 User
裡面應該要有的資料。Sequelize
能夠讓我們使用 ORM 框架來開發網頁,以(物件導向的)程式語言例如 JavaScript 等來使用資料庫。
import { Model } from 'sequelize';
export class User extends Model {
public id!: number; // Note that the `null assertion` `!` is required in strict mode.
public nonce!: number; // 前述提到的 nonce
public publicAddress!: string; // 也就是使用者以太坊錢包的地址
public username?: string; // 可為空
}
這邊做 Sequelize Init
,決定語言為 sqlite
,比較重要的是 storage
這個參數是只屬於 sqlite
,預設為 ':memory:'
。
import os from 'os';
import path from 'path';
import { INTEGER, Sequelize, STRING } from 'sequelize';
const sequelize = new Sequelize('login-with-metamask-database', '', undefined, {
dialect: 'sqlite', // connector library
storage: path.join(os.tmpdir(), 'db.sqlite'), // 這裡儲存在預設的作業系統暫存資料夾
logging: false,
});
...
sequelize.sync();
export { sequelize };
初始化 User
的資料結構以及內部資料型態的定義,這邊已經將 nonce
的加密規則宣告了,唯一個很大很大的整數,其中要確認 nonce
改變才能稱作成功登入。
import { User } from './models';
User.init(
{
nonce: { // 欄位名稱
allowNull: false, // 能否為空
type: INTEGER.UNSIGNED, // SQLITE will use INTEGER // 資料型態
defaultValue: (): number => Math.floor(Math.random() * 10000), // Initialize with a random nonce
},
publicAddress: {
allowNull: false,
type: STRING,
unique: true,
validate: { isLowercase: true }, // 詳見下列說明
},
username: {
type: STRING,
unique: true,
},
},
{
modelName: 'user',
sequelize, // This bit is important
timestamps: false,
}
);
比較特別的是如何確認以太坊錢包的地址是合規的,為了簡化步驟所以這裡先假設全部都小寫。詳細部分可以參考以下的文章。
How can I check if an Ethereum address is valid?
【Express】
先做基本的宣告。這邊使用 Express
來對 Middlewares
對 request 的中間層進行處理,
import './db';
import bodyParser from 'body-parser';
import cors from 'cors';
import express from 'express';
import { services } from './services';
const app = express();
// Middlewares
app.use(bodyParser.json()); // 令 json 可使用
app.use(cors()); // 允許 express server 能夠透過瀏覽器被其他 domain 取用
// Mount REST on /api
app.use('/api', services); // 把服務上呈,服務內容在明天會介紹
const port = process.env.PORT || 8000;
app.listen(port, () =>
console.log(`Express app listening on localhost:${port}`)
);
【小結】
因為對 Sequelize
、Express
並沒有很熟悉,這幾天都過得很痛苦阿! 主要是在資料庫的部分有很大的空缺,此外對 web3 的使用也還沒學好,所以此時此刻還同時先學後面的東西嗚嗚。
【參考資料】
One-click Login with Blockchain: A MetaMask Tutorial
28. Docker - Docker Compose - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
Sequelize
[week 17] 後端中階 - 淺談 Sequelize:使用 ORM 框架串接資料庫 - HackMD
Using Sequelize.js and SQLite in an Express.js App
Creating App Using Express.JS + Sequelize ORM
路由