Vue+Koa+Mongodb 小練習
作者: Pawn
本文首發: Pawn部落格
功能: 基於vue koa mongodb進行登入,註冊,留言的簡單網站。
體驗地址: demo.lcylove.cn
github: github.com/LiChangyi/d…
前面的話
原因
- 前段時間用vue+koa+mongodb搭建了一個個人部落格,因為是第一次寫前後互動,發現有很多地方不是特別的完善,同時程式碼對於新學者來說可讀性也不是很大。所以這個小練習,從一個簡單的方面入手,希望能給踩過同樣多坑的同路人一點啟發。
- 在我今年年初在學習vue以及koa的時候,網上對這方面的內容,都是一個完整的專案,檔案太多,觀看難度太大,其次是,都對圖片的上傳都沒怎麼涉及。
- 我在學習部署koa和vue的專案的時候,網上的知識很零碎,這裡我會歸納一下。
涉及知識點
- vue全家桶的使用
- 在vue中使用axios,並配置它
- koa與mongoose的基本使用
- jsonwebtoken的使用以及前後臺鑒定登入
注: 本文面對剛學vue或者koa不久或者想了解一個簡單的前後臺互動的問題的同學,涉及基礎。
預覽
感興趣的問題
我在程式碼裡面寫了很多的註釋方便閱讀,這裡簡單說一下我個人當初學習的時候比較疑惑為問題
一些小變動
前端直接採用vue-cli進行一個基礎的專案骨架。然後由於是一個簡單的專案,所以頁面就隨便寫一下,主要是實現功能。
因為我們在伺服器上面採用的是二級域名的形式,所以需要在 config/index.js
下面的 build
項裡面將 assetsPublicPath
設定成相對路徑。
assetsPublicPath: ''
複製程式碼
我們在本地開發的時候需要進行除錯,需要用到代理,不然就只有設定後臺允許跨域。所以在 config/index.js
下面的 dev
物件裡面新增:
proxyTable: {
'/api':{ // 只代理 /api url下的請求
target: "http://localhost:7778", // 後臺伺服器的地址
changeOrigin: true
}
}
複製程式碼
如何讓伺服器端記住你(jsonwebtoken)
HTTP請求是無狀態的,意思是他記不住你這個人是誰,他只知道你要什麼資源,然後給你什麼。但是實際問題是當使用者給我們尋求資源的時候,我們應該要考慮應該給他這個資源。對這個人的身份做一個判別,然後在做決定給他什麼樣的資源。
所以針對每個使用者我們需要用一個唯一的標識來確定他,這就是為什麼需要登入才能操作,登入的目的就是讓服務端產生一個認識你的標識,以後你的每次請求都要帶上去。
在前後臺不分離的時候,伺服器端往往會在客服端放一個SessionId
或者一個cookie
的東西。但是現在前後端分離以後,我們登入成功,伺服器端應該也會給我們這樣一個唯一標識身份的字串。然後我們在每次請求資料的時候帶上它。這裡我伺服器端採用的是jsonwebtoken
來製造這個唯一標識,程式碼詳情 => server/utils/token.js
然後我寫了一箇中介軟體check_token
來判斷如果這個資源需要登入,就會去檢查他的token如果token不對那麼就直接丟擲錯誤。
前端拿到服務端的token後我們需要把他存放起來這裡大概會有2種方式:
- 存在vuex 裡面, 這種方式有一個弊端就是,網頁一重新整理vuex裡面的資料就清空了。就意味著要重新登入。
- 存在sessionStorage裡面,採用瀏覽器的會話儲存,只有當瀏覽器關閉的時候才會清空資料。
這裡我把2種方法結合起來,得到token的時候把他同時存放在vuex和sessionStorage裡面,存放在vuex裡面是為了操作方便,存放在sessionStorage是為了保持重新整理頁面的時候資料不丟失。在前端每次向後臺請求資料的時候,帶上這個token,詳見程式碼 => client/src/axios/index.js
關於一些網上的爭論:
Q :有人說,讓客服端存放token不安全,或者說用sessionStorage方法來存放不安全,因為存在著csrf問題
A :沒有絕對的安全,我個人瞭解到就是用以前的cookie
或者SessionId
也存在著這樣的問題。想要解決這個問題就儘量的吧網頁升級成https,或者,採用伺服器中轉的方式,在2者之間在加入一個伺服器端,把真實的token存放在中轉,然後客服端與中轉進行通訊。
驗證碼的識別
驗證碼的生成我採用了gd-bmp
包具體用法,看server/controller/other.js
同樣根據上面的介紹,http是沒有狀態的,我們要驗證驗證碼的正確性,應該對每個驗證碼增加一個唯一的標識,然後存放在資料,當使用者登入或者使用者註冊用到驗證碼的時候,把驗證碼和相應的驗證碼標識一起發往後臺,然後判斷驗證碼的正確與否。對於驗證碼及標識的儲存,我這裡為了方便就是採用mongodb來儲存,但是網上很多人推薦用redis來儲存。
本地圖片的上傳
這個問題從很久以前就很迷惑,一直不知道如何上傳圖片到伺服器。即使h5出現了<input type="file">
但是解決這個問題也是很麻煩。我個人覺得上傳圖片應該有2種方式:
- 直接用過input的onchang事件獲取到的檔案,來上傳二進位制檔案。
- 將圖片轉換成base64來進行上傳
我這裡採用的是第二種,用base64上傳圖片,然後自己吧base64字串儲存進資料庫,因為操作比較方便。當然你也可以在伺服器端吧base64轉換成二進位制檔案存放在伺服器裡面,然後把檔案地址儲存在資料庫裡面。也可以在本地直接上傳二進位制檔案,如果你採用這個方式,那麼你應該在koa裡面在加入一個處理file請求的中介軟體。
也可以藉助第三方的儲存,比如我在我的部落格裡面寫了一個介面就是直接在客服端上傳檔案到七牛雲,然後七牛雲返回給我連結。當時之所以採用這個操作是因為,小水管伺服器太慢了,藉助第三方載入圖片會快很多。
關於專案的伺服器部署
因為vue的簡單,很多都只知道npm install
和 npm run dev
所以有很多人會有疑問,那就是我這個vue專案如何部署在伺服器上面?難道是把程式碼上傳到伺服器上面來執行上面2條命令嗎?
其實這個問題是由於大家只會機械式操作留下的,因為vue-cli的簡單方便已經mvvm框架的厲害,我們忘記了我們寫的東西本子上還是網頁。所以我們需要用webpack
將我們的專案打包一下在命令列裡面執行npm run build
將我們寫的vue和js程式碼以及其他的資原始檔,打包/dist
裡面。這裡面的檔案就是我們寫的網頁,,我們只需要吧這裡面的檔案上傳到伺服器下就可以執行了。
這裡關於把打包出來的檔案往往會有2方式執行:
- 將檔案丟到
server/public
資料夾下面,因為我們在server/app.js
下面配置了靜態檔案目錄,然後我們啟動服務端。就可以在127.0.0.1:7778/index.html
(假設伺服器埠號是7778)看到我們的網頁。 - 用nginx伺服器代理 ,靜態檔案用nginx託管,然後設定轉發的方式來獲取api請求資料。
其實第一種的話也是藉助與nodejs會自動啟動一個伺服器,進行靜態檔案的託管。我個人比較喜歡第二種方法,下面我們就進行這種檔案的配置。
開始之前,你應該檢查你的伺服器是否安裝有nginx
與pm2
$ pm2 -v
$ nginx -v
複製程式碼
如果正確出現版本號,那麼就已經安裝了,如果沒有的話,請谷歌安裝。pm2
的作用是進行程式守護,當你的nodejs意外的停止的時候,進行重啟。
如果我們有域名的話,我們現在域名商哪裡新增一個二級域名解析。這裡新增完解析以後會要幾分鐘的等待時間
然後,我們找到nginx的配置檔案nginx.conf
在裡面加入:
server {
listen 80;
server_name demo.lcylove.cn;
root /data/www/demo;
index index.html index.htm index.php;
location /api/ {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $http_host;
proxy_pass http://127.0.0.1:7778;
}
}
複製程式碼
注意: location /api/
這裡說明只有api/*的請求才會進行轉發。
然後進行nginx伺服器的重啟:nginx -s reload
我們把server的程式碼放在伺服器下,通過命令列移到相應位置執行命令:
$ npm install && cnpm i
$ pm2 start --name demo1 npm -- run start
複製程式碼
啟動我們的nodejs伺服器。然後我們就可以開啟網站 demo.lcylove.cn 檢視效果
最後
由於本人才疏學淺,如果有任何問題的歡迎下面留言討論!