Wondering where to go? Wandermap!
☞ 介紹影片點這邊
提供戶外行程路線地點的檢視以及記錄心得行程的開放論壇平台。其中又以 健行筆記 與 臺灣山林悠遊網 的部份頁面作為功能與頁面的參考。再以地圖搜尋為特色,主打此功能增加差異性,改善使用者體驗。
提供一個開放的交流平台。使用者可以檢視閱覽路線及地點詳細的資訊,並且分享自己的行程記錄。
作為 wandermap 的後端專案。使用 express 作為 web 框架、MySQL 儲存資料。
進行第三正規化,以主鍵與外鍵解決遞移相依的關係。設定 ON DELETE/UPDATE CASCADE,在參考的外鍵變動時,自動進行修改。
設定索引與利用 EXPLAIN 語句檢查 SQL 執行效率並改進。未使用 prepared statement,但使用的套件會將字串做跳脫,自行嘗試進行 SQL injection 未果。
使用者註冊登入後,會得到 member 身分。即有權限可以對心得、步道做按讚、收藏的動作。而管理員 (admin) 可以改動其他會員的權限、查看所有使用者資料。會員身分改為停權 (suspended) 後,能做的操作與未註冊者無異。
使用者底下有自己的 todo list,只有本人和管理員看得到、能做 CRUD。提供使用者在行前準備時,能有自己的清單可以清點裝備與提醒事項。
只有管理員能新增、更新、刪除步道。一般使用者只能查詢、收藏步道、針對步道做評論。
資料來源為 林務局開放資料。取得所有步道時,提供以海拔高度、步道長度、難度、地點、關鍵字篩選後的搜尋結果。也提供 cursor、offset/limit 兩種分頁功能,在回傳的 http header 帶有 x-total-count 表示此搜尋條件下的資料總筆數,使前端能自製分頁。
管理員可以做所有操作。會員可以對自己的心得做所有 CRUD 操作,也能對其他心得按讚留言。
發布文章時可填寫 tags 欄位,在取得所有心得時可針對特定 tag 做搜尋。提供 cursor、offset/limit 兩種分頁功能,在回傳的 http header 帶有 x-total-count 表示此搜尋條件下的資料總筆數,使前端能自製分頁。
登入成功時時產生 JWT token,方便前端 react app 取得使用者資料,減少與伺服器連線次數。過期時間較短,預設為 1 小時。
同時將產生 refresh token,以 cookie 形式儲存在瀏覽器。作為 JWT token 過期時,使用者不需再次登入即可取得新 JWT 的機制。有設定 httpOnly 等屬性以提高安全性。過期時間較長,預設為 1 個月。
若因故,後端想要讓使用者重新登入,只要主動使 session 失效,前端在 JWT 過期就就必須重新登入。
利用 swagger 產生符合 OpenAPI 規範的文件,並建立測試頁面。方便開發者快速了解、測試 API。
收到 request、發出 SQL query 與遇到錯誤時,將訊息寫入 /logs
路徑下,提供開發者除錯。
- 把
.env.example
改名成.env
。打開檔案填入等號後面的值。 $ npm install
:安裝所需套件。$ npm run build
:在 database 建立所需的 table,並帶入 tags、trails 兩張 table 的資料。
-
$ npm run start
:運行應用程式。 -
$ npm run dev
:測試用,程式碼變動時會自動重啟應用程式。
由於 refresh token 是以 SameSite=None; Secure
的 cookie 傳送,所以正式運行服務需要申請 SSL 憑證。
獲得 SSL 的未加密私鑰與憑證後,將檔案路徑設定在 .env
的 SSL_KEY
、SSL_CERTIFICATE
。之後 $ npm run dev
、$ npm run start
都會自動啟用 https 伺服器。
用 certbot 申請 SSL 憑證
步驟可參考 certbot 官網 或 Will 保哥的文章。
大致上流程是用 snapd 套件管理系統安裝 certbot,用 certbot 向 Let's Encrypt 完成一系列確認網域所有權的挑戰,取得憑證並自動更新。
以 ubuntu 20.04 LTS 作為環境進行示範。
$ sudo apt update && sudo apt install snapd
:安裝 snapd。$ sudo snap install core; sudo snap refresh core
:確認 snapd 是最新版本。$ sudo apt-get remove certbot
:移除舊有的 certbot。$ sudo snap install --classic certbot
:用 snap 安裝 certbot。$ sudo ln -s /snap/bin/certbot /usr/bin/certbot
:確保可以執行$ certbot
指令。$ cd <path_to_project_directory>
進入專案根目錄,創資料夾$ mkdir ./src/public
。$ npm run start
或$ npm run dev
把伺服器跑起來。$ sudo certbot certonly --webroot
:用 certbot 申請憑證。接下來有一系列問答,根據需求填入值,可參考 Will 保哥的文章。在Input the webroot for <www.your-domain.com.tw>:
這個問題填入<path_to_project_directory>/src/public
。- 將金鑰與憑證的路徑填入
.env
檔案。範例為SSL_KEY=/etc/letsencrypt/live/<www.your-domain.com.tw>/privkey.pem
、SSL_CERTIFICATE=/etc/letsencrypt/live/<www.your-domain.com.tw>/fullchain.pem
。 $ sudo certbot renew --webroot --dry-run
,確認排程能夠自動更新憑證。
功能尚在撰寫中。
$ docker build -t <image_name> .
:從 Dockerfile 建立 image。
$ docker run -dp <host_port>:<container_port> --name <container_name> --env-file ./.env <image_name>
:從 image 建立 container,並讀入環境變數。
$ docker-compose up -d
:由 docker-compose.yml 一次建立多個 container,並在背景執行。
$ docker-compose down
:停止 docker-compose。
.
├── .env # 環境變數存放處
├── .env.example # 環境變數的範例
├── .git
├── .gitignore
├── .dockerignore # docker 部署時需要的檔案們(新功能即將上線,請耐心等候)
├── Dockerfile
├── docker-compose.dev.yml
├── docker-compose.yml
├── node_modules
├── package-lock.json
├── package.json
├── LICENSE
├── README.md
├── logs # 存放 log 的資料夾(app 會自動建立)
├── databaseStructure.sql # 建立資料庫 table 的 sql
├── tagAndTrailData.sql # tags 與 trails 兩張 table 資料的 sql
└── src # 程式碼在此 ฅ•ω•ฅ
├── constants
│ ├── errors.js # 伺服器在特定狀況下回應的錯誤訊息
│ └── location.js # 地區與縣市的對照 map
├── controllers # 收到 http request 後的邏輯處理
│ ├── articles.js
│ ├── todos.js
│ ├── trails.js
│ └── users.js
├── db.js # 設定資料庫連線
├── index.js # application server 進入點
├── logger.js # logger 的設定
├── build.js # npm run build 建立資料庫架構及匯入資料
├── middlewares # 自訂的 middlewares
│ ├── auth.js # 檢查 jwt 是否被竄改或過期,沒問題就放進 res.locals.tokenPayload 變數中
│ ├── logRequest.js # 把收到的請求寫入 log
│ └── validators.js # 驗證使用者輸入
├── models # 與資料庫互動的介面
│ ├── articles.js
│ ├── refreshTokens.js
│ ├── todos.js
│ ├── trails.js
│ └── users.js
├── routers # 路由們,底下的資料夾可區分 api 版本
│ ├── api # 第一版 api
│ │ ├── articles.js
│ │ ├── index.js # router 進入點
│ │ ├── schemas # swagger.js 需要讀的資料們
│ │ │ └── userSchema.yaml
│ │ ├── swagger.js # 讀 router 的註解與 ./schemas/*.yaml 產生符合 OpenAPI 規範的資料
│ │ ├── trails.js
│ │ └── users.js
│ └── apiv2 # 第二版 api placeholder
│ └── index.js
└── utils.js # 可重複利用的函式們
套件 | 敘述 |
---|---|
express | Node.js 的 web 框架 |
express-validator | 客製化驗證使用者輸入的 middleware |
cors | 處理 cross origin resource sharing 相關設定的 middleware |
cookie-parser | 解析 header 的 signed cookie 並放入 req.signedCookies 變數 |
dotenv | 在 .env 設置環境變數供程式碼存取 |
nodemon | 開發測試用套件,在程式碼改動時自動重啟應用程式 |
swagger-jsdoc | 產生符合 OpenAPI (Swagger) specification 的文件 |
swagger-ui-express | 用符合 OpenAPI 規範的文件產生 UI 介面,提供 API 測試 |
winston | 提供客製化 logger |
winston-daily-rotate-file | log rotation |
jsonwebtoken | 產生及認證 JWT 合法性 |
bcrypt | 將密碼加鹽雜湊 |
mysql2 | 連線操作資料庫 |
其他 | 敘述 |
---|---|
AWS EC2 | 後端專案部署的平台 |
prettier | 自動排版 |
pm2 | daemon process manager |
certbot | 申請 SSL 憑證 |
👤 @cmtilo
. __ ∧ ∧
/\ (*゚∀゚)\ 專案構想、wireframe 繪製、
\/| ̄ ̄∪ ∪ ̄|\ 前端(會員個人頁面(公開&會員)、
\| Cmt | 新增步道頁面、新增心得頁面)
 ̄ ̄ ̄ ̄ ̄
. __ ∧ ∧
/\ (*゚∀゚)\ 專案雛形發想、wireframe 繪製、
\/| ̄ ̄∪ ∪ ̄|\ 前端(管理員後台、單一步道頁面)、
\| Dylan | 後端(trail API、article API、swagger 文件、部署)
 ̄ ̄ ̄ ̄ ̄
👤 @torai55
. __ ∧ ∧
/\ (*゚∀゚)\ 專案構想、資料庫規劃
\/| ̄ ̄∪ ∪ ̄|\ 後端(user API、article API、trail API、
\| Torai | 權限控制、logger、API 文件、swagger 文件、部署)
 ̄ ̄ ̄ ̄ ̄
. __ ∧ ∧
/\ (*゚∀゚)\ 專案構想、wireframe 繪製、
\/| ̄ ̄∪ ∪ ̄|\ 前端 (功能測試(google map, 圖片上傳, ckeditor 串接)、
\| Yu | 首頁、全部步道頁面、會員系統、部署)
 ̄ ̄ ̄ ̄ ̄
. __ ∧ ∧
/\ (*゚∀゚)\ 專案雛形發想、專案構想、wireframe 繪製、
\/| ̄ ̄∪ ∪ ̄|\ 前端 (單一心得頁面、全部心得頁面)、
\| Ader | 後端(article API)
 ̄ ̄ ̄ ̄ ̄