---
# System prepended metadata

title: Member Service 設計

---

# Member Service

## 架構介紹
models.py 實作資料的存取，
service.py 實作業務邏輯
servicer.py 實作gRPC API介面

在k8s實作:
liveness: 確認服務活著
readliness: 確認可以接流量

## 功能需求

* 使用者分成
    * 一般民眾
    * 企業
        * 後臺管理者：管理員工權限、審核誰可以加入
        * 企業使用者：後臺管理者將員工拉到此帳號底下或是員工申請加入企業
* 每個人都有免費版功能，企業帳號可以購買付費版，公司下面的一般user也可以有付費版功能
* 輸入使用者帳號、密碼，可以註冊或登入
* 註冊時須輸入(必填)：帳號(使用者名稱)、密碼、email
* 註冊時驗證email
* 所有使用者可以看到自己的使用者管理頁面

## DB Schema

### Member

- 使用 PostgreSQL

```sql
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

CREATE TABLE users (
    uid UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
    account VARCHAR(50) NOT NULL UNIQUE,
    password TEXT NOT NULL,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100) UNIQUE
);
```

## gRPC API Spec

### SignUp(account, password, name, email)

### Login (account, password)

### GetUserByID(id)

## 資料庫安全

### 資料儲存安全準則
1. 帳號和密碼可以存在同一個table，但是[密碼需要hash加鹽或 Bcrypt](https://medium.com/starbugs/how-to-store-password-in-database-sefely-6b20f48def92) 
2. 機敏資料需要和儲存帳號密碼資料等存在不同的table，且內容需要加密(AES金鑰存在本機)
3. 根據最小權限原則: 使用不同的SQL使用者(Role)並設定權限，比如用來查詢登入使用者的user不能夠看存機敏資料的table
4. 針對有時效的資料(如OTP、email認證等)需要有一個token並儲存在獨立的table中，而且要做好時效性驗證
5. (再看看，更安全但麻煩)將SQL查詢的資料用key做AES加解密，key統一由KMS(雲端)管理
    * AWS、GCP等雲端都有自己的KMS，也有其他開源可以自己架的KMS
    * KMS的好處在於使用者無法知道自己使用的金鑰

### 資料查詢安全準則
1. 參數化查詢(Parameterized Queries) 或 ORM(沒用過)
    * 絕對不准使用eval()
3. 無法參數化查詢的欄位(如欄位名、表格名、ORDER BY 的欄位)就使用白名單
4. 限制SQL使用者的讀寫權限
5. 引用WAF，過濾惡意payload
    * AWS等有自己的WAF
    * OWASP官方開源: [ModSecurity + OWASP Core Rule Set (CRS)](https://medium.com/@jieshiun/%E5%A6%82%E4%BD%95%E5%9C%A8-ubuntu-22-04-%E5%AE%89%E8%A3%9D-nginx-%E8%88%87-modsecurity-26f744223dca)
