Koa框架——coderhub实战
https://github.com/zep03/koa-coderhub/commits/main
一、coderhub功能接口說明
Coderhub旨在創(chuàng)建一個程序員分享生活動態(tài)的平臺。
完整的項(xiàng)目接口包括:
完成的功能如下:
1.用戶管理系統(tǒng)
2.內(nèi)容管理系統(tǒng)
3.內(nèi)容評論管理
4.內(nèi)容標(biāo)簽管理
5.文件管理系統(tǒng)
其他功能其實(shí)都是非常相似的
二、項(xiàng)目的搭建
功能一:目錄結(jié)構(gòu)的劃分:
功能二:應(yīng)用配置信息寫到環(huán)境變量
npm 官方文檔的這樣介紹 dotenv: Dotenv 是一個零依賴的模塊,它能將環(huán)境變量中的變量從 .env 文件加載到 process.env 中。
功能三:創(chuàng)建和啟動服務(wù)器
- 基于koa創(chuàng)建app;
-啟動服務(wù)器;
三、用戶注冊接口
用戶注冊接口編寫流程:
數(shù)據(jù)庫連接操作:mysql2
5. 創(chuàng)建數(shù)據(jù)庫連接;
6. 測試數(shù)據(jù)庫連接是否成功;
注冊用戶校驗(yàn)
密碼加密存儲:
四、用戶登錄接口
用戶登錄接口編寫流程:
實(shí)現(xiàn)動態(tài)加載路由:
驗(yàn)證的中間件:
3. 賬號和密碼是否為空;
4. 用戶名是否存在;
5. 校驗(yàn)密碼是否一致;
登錄成功返回憑證:
6. cookie+session;
7. Token令牌;
五、為什么需要登錄憑證呢?
web開發(fā)中,我們使用最多的協(xié)議是http,但是http是一個無狀態(tài)的協(xié)議。
無狀態(tài)的協(xié)議?什么叫做無狀態(tài)協(xié)議呢?
舉個例子:
我們登錄了一個網(wǎng)站 www.coderhub.com(當(dāng)然這個網(wǎng)站不存在,是我要開發(fā)一個的);
登錄的時候我們需要輸入用戶名和密碼:比如用戶名coderwhy,密碼Coderwhy666.;
登錄成功之后,我們要以coderwhy的身份去訪問其他的數(shù)據(jù)和資源,還是通過http請求去訪問。
- coderhub的服務(wù)器會問:你誰呀?
- coderwhy說:我是coderwhy呀,剛剛登錄過呀;
- coderhub:怎么證明你剛剛登錄過呀?
- coderwhy說:這。。。,http沒有告訴你嗎?
- coderhub:http的每次請求對我來說都是一個單獨(dú)的請求,和之前請求過什么沒有關(guān)系。
看到了吧?這就是http的無狀態(tài),也就是服務(wù)器不知道你上一步做了什么,我們必須得有一個辦法可以證明我們登錄過。
六、認(rèn)識cookie
Cookie(復(fù)數(shù)形態(tài)Cookies),又稱為“小甜餅”。類型為“小型文本文件,某些網(wǎng)站為了辨別用戶身份而存儲在用戶本地終端(Client Side)上的數(shù)據(jù)。
- 瀏覽器會在特定的情況下攜帶上cookie來發(fā)送請求,我們可以通過cookie來獲取一些信息;
Cookie總是保存在客戶端中,按在客戶端中的存儲位置,Cookie可以分為內(nèi)存Cookie和硬盤Cookie。
- 內(nèi)存Cookie由瀏覽器維護(hù),保存在內(nèi)存中,瀏覽器關(guān)閉時Cookie就會消失,其存在時間是短暫的;
- 硬盤Cookie保存在硬盤中,有一個過期時間,用戶手動清理或者過期時間到時,才會被清理;
如何判斷一個cookie是內(nèi)存cookie還是硬盤cookie呢?
- 沒有設(shè)置過期時間,默認(rèn)情況下cookie是內(nèi)存cookie,在關(guān)閉瀏覽器時會自動刪除;
- 有設(shè)置過期時間,并且過期時間不為0或者負(fù)數(shù)的cookie,是硬盤cookie,需要手動或者到期時,才會刪除;
七、cookie常見的屬性
cookie的生命周期:
- 默認(rèn)情況下的cookie是內(nèi)存cookie,也稱之為會話cookie,也就是在瀏覽器關(guān)閉時會自動被刪除;
- 我們可以通過設(shè)置expires或者max-age來設(shè)置過期的時間;
expires:設(shè)置的是Date.toUTCString(),設(shè)置格式是;expires=date-in-GMTString-format;
max-age:設(shè)置過期的秒鐘,;max-age=max-age-in-seconds (例如一年為60*60*24*365);
cookie的作用域:(允許cookie發(fā)送給哪些URL)
- 如果不指定,那么默認(rèn)是 origin,不包括子域名。
- 如果指定Domain,則包含子域名。例如,如果設(shè)置 Domain=mozilla.org,則 Cookie 也包含在子域名中(如developer.mozilla.org)。
例如,設(shè)置 Path=/docs,則以下地址都會匹配:
/docs
/docs/Web/
/docs/Web/HTTP
八、客戶端設(shè)置cookie
js直接設(shè)置和獲取cookie:
這個cookie會在會話關(guān)閉時被刪除掉:
設(shè)置cookie,同時設(shè)置過期時間(默認(rèn)單位是秒鐘):
九、服務(wù)器設(shè)置cookie
Koa中默認(rèn)支持直接操作cookie
- /test請求中設(shè)置cookie
- /demo請求中獲取cookie
十、Session是基于cookie實(shí)現(xiàn)機(jī)制
在koa中,我們可以借助于 koa-session 來實(shí)現(xiàn)session認(rèn)證:
設(shè)置secrets加密字符串,用于加密數(shù)據(jù):
十一、認(rèn)識token
cookie和session的方式有很多的缺點(diǎn):
- Cookie會被附加在每個HTTP請求中,所以無形中增加了流量(事實(shí)上某些請求是不需要的);
- Cookie是明文傳遞的,所以存在安全性的問題;
- Cookie的大小限制是4KB,對于復(fù)雜的需求來說是不夠的;
- 對于瀏覽器外的其他客戶端(比如iOS、Android),必須手動的設(shè)置cookie和session;
- 對于分布式系統(tǒng)和服務(wù)器集群中如何可以保證其他系統(tǒng)也可以正確的解析session?
所以,在目前的前后端分離的開發(fā)過程中,使用token來進(jìn)行身份驗(yàn)證的是最多的情況:
- token可以翻譯為令牌;
- 也就是在驗(yàn)證了用戶賬號和密碼正確的情況,給用戶頒發(fā)一個令牌;
- 這個令牌作為后續(xù)用戶訪問一些接口或者資源的憑證;
- 我們可以根據(jù)這個憑證來判斷用戶是否有權(quán)限來訪問;
所以token的使用應(yīng)該分成兩個重要的步驟:
- 生成token:登錄的時候,頒發(fā)token;
- 驗(yàn)證token:訪問某些資源或者接口時,驗(yàn)證token;
十二、JWT實(shí)現(xiàn)Token機(jī)制
JWT生成的Token由三部分組成:
- alg:采用的加密算法,默認(rèn)是 HMAC SHA256(HS256),采用同一個密鑰進(jìn)行
加密和解密; - typ:JWT,固定值,通常都寫成JWT即可;
- 會通過base64Url算法進(jìn)行編碼;
- 攜帶的數(shù)據(jù),比如我們可以將用戶的id和name放到payload中;
- 默認(rèn)也會攜帶iat(issued at),令牌的簽發(fā)時間;
- 我們也可以設(shè)置過期時間:exp(expiration time);
- 會通過base64Url算法進(jìn)行編碼
- 設(shè)置一個secretKey,通過將前兩個的結(jié)果合并后進(jìn)行HMACSHA256的算法;
- HMACSHA256(base64Url(header)+.+base64Url(payload), secretKey);
- 但是如果secretKey暴露是一件非常危險的事情,因?yàn)橹缶涂梢阅M頒發(fā)token,也可以解密token;
十三、Token的使用
當(dāng)然,在真實(shí)開發(fā)中,我們可以直接使用一個庫來完成: jsonwebtoken;
十四、非對稱加密
前面我們說過,HS256加密算法一單密鑰暴露就是非常危險的事情:
- 比如在分布式系統(tǒng)中,每一個子系統(tǒng)都需要獲取到密鑰;
- 那么拿到這個密鑰后這個子系統(tǒng)既可以發(fā)布另外,也可以驗(yàn)證令牌;
- 但是對于一些資源服務(wù)器來說,它們只需要有驗(yàn)證令牌的能力就可以了;
這個時候我們可以使用非對稱加密,RS256:
- 私鑰(private key):用于發(fā)布令牌;
- 公鑰(public key):用于驗(yàn)證令牌;
我們可以使用openssl來生成一對私鑰和公鑰:
- Mac直接使用terminal終端即可;
- Windows默認(rèn)的cmd終端是不能直接使用的,建議直接使用git bash終端;
十五、使用公鑰和私鑰簽發(fā)和驗(yàn)證簽名
注意:
十六、派發(fā)令牌和驗(yàn)證令牌
postman中設(shè)置全局變量token:
十七、發(fā)布和查詢動態(tài)內(nèi)容
創(chuàng)建新的表 moment
定義發(fā)布動態(tài)內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- Controller和Service中處理內(nèi)容
定義查詢單個內(nèi)容的接口
- 根據(jù)momentId查詢接口內(nèi)容;
定義查詢多條內(nèi)容的接口
- 查詢所有moment接口內(nèi)容(根據(jù)offset和limit決定查詢數(shù)量)
十八、修改和刪除動態(tài)內(nèi)容
定義修改動態(tài)內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- 驗(yàn)證用戶的權(quán)限
- Controller和Service中的處理
定義刪除內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- 驗(yàn)證用戶權(quán)限
- Controller和Service的處理
十九、發(fā)表和修改評論內(nèi)容
注意:
關(guān)系表的級聯(lián)更新: on update cascade
on delete cascade 是級聯(lián)刪除的意思
意思是 當(dāng)你更新或刪除主鍵表時,那么外鍵表也會跟隨一起更新或刪除
創(chuàng)建新的表 comment
定義發(fā)布評論內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- Controller和Service中處理內(nèi)容
回復(fù)評論接口:
定義修改評論內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- 驗(yàn)證用戶的權(quán)限
- Controller和Service中的處理
二十、刪除和查詢評論內(nèi)容
定義刪除評論內(nèi)容的接口
- 定義路由接口
- 驗(yàn)證用戶登錄
- 驗(yàn)證用戶權(quán)限 p Controller和Service的處理
查詢動態(tài)的時候,同時顯示評論信息
- 查詢多個動態(tài)時,顯示評論的個數(shù)
- 查詢單個動態(tài)時,顯示評論的列表
根據(jù)動態(tài)的id獲取評論詳情:
二十一、標(biāo)簽接口開發(fā)
創(chuàng)建標(biāo)簽的表
定義創(chuàng)建標(biāo)簽接口
- 路由配置Router
- 驗(yàn)證用戶登錄
- 創(chuàng)建標(biāo)簽
創(chuàng)建標(biāo)簽和動態(tài)關(guān)系表
定義給動態(tài)添加標(biāo)簽的接口
- 給動態(tài)添加新的接口
查詢所有標(biāo)簽列表:
查詢標(biāo)簽接口
- 查詢動態(tài)列表,展示標(biāo)簽數(shù)量
- 根據(jù)動態(tài)id,展示標(biāo)簽列表
二十二、上傳頭像圖片
上傳頭像邏輯:
分析實(shí)現(xiàn)思路:
- 1.圖片(文件)上傳 /upload/avatar
目的:服務(wù)器端可以保存一張圖片 - 2.提供一個接口,可以讓用戶獲取圖片
/1/avatar -> 找到圖片\讀取圖片\content-type: image/jpeg\返回圖像的信息 - 3.將URL存儲到用戶信息中
avatarURL: 頭像的地址 - 4.獲取信息時,獲取用戶的頭像
1. 定義上傳圖像的接口,將用戶上傳的圖片保存到服務(wù)器本地的uploads/avatar文件夾下,然后再把圖片的信息保存到數(shù)據(jù)庫中的avatar表中:
2. 定義獲取圖像的接口
3. 請求用戶信息時,獲取頭像
3.1 修改上傳頭像接口,不僅要把上傳的頭像信息保存到數(shù)據(jù)庫的avatar表中,還要將上傳的用戶頭像的avatarUrl保存到數(shù)據(jù)庫的用戶表中:
3.2 修改原來的動態(tài)查詢接口,增加avatarUrl字段:
二十三、上傳動態(tài)的配圖
上傳動態(tài)配圖
- 定義上傳動態(tài)配圖的接口
- 定義獲取動態(tài)配圖的接口
- 獲取動態(tài)時,獲取配圖信息
1. 定義上傳動態(tài)配圖的接口
2. 定義獲取動態(tài)配圖的接口
3. 獲取動態(tài)時,獲取配圖信息
根據(jù)momentId獲取動態(tài)的配圖:
附加:處理上傳的圖片,將圖片分成三種大小
JavaScript 編寫的圖像處理庫 Jimp:https://github.com/oliver-moran/jimp
https://github.com/oliver-moran/jimp/tree/master/packages/plugin-resize
然后修改獲取動態(tài)配圖的接口:
總結(jié)
以上是生活随笔為你收集整理的Koa框架——coderhub实战的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mongoose 数据校验
- 下一篇: 解决后端返回数据中的大数字问题(使用第三