iT邦幫忙

2021 iThome 鐵人賽

DAY 12
0
Modern Web

All In One NFT Website Development系列 第 12

Day 12【連動 MetaMask - Backend & Init】277353

xgdoq0qpcdg41.jpg

【前言】
大家安安,今天的主題經過 MetaMask 強大的功能之後其實是可以省略的。開玩笑的,反正不管怎樣我都要把這個系統做到最好!接下來要說的是後端架設、基本資料結構的宣告與初始化。今天的內容大部份都參考來自 Amaury Martiny 的 One-click Login with Blockchain: A MetaMask Tutorial!

【Back-End 使用】
在這邊我是用 Node.js, Express, and SQLite 來做為後端架設,下載以及相關學習的部分就跳過否則太冗長而且有些偏離主題了,大家可以去參考別的文章,他們有很詳細又不錯的內容!

在 WSL 上開始使用 Docker 容器

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}`)
);

【小結】
因為對 SequelizeExpress 並沒有很熟悉,這幾天都過得很痛苦阿! 主要是在資料庫的部分有很大的空缺,此外對 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
路由


上一篇
Day 11【連動 MetaMask - Pop Up & Login Detection】Can`t use current password.
下一篇
Day 13【連動 MetaMask - Back-End Services】這顯然是廠商的疏失
系列文
All In One NFT Website Development30

尚未有邦友留言

立即登入留言