之前寫(xiě)了一篇介紹token的文章:簡(jiǎn)單理解Token機(jī)制,token算法自己設(shè)計(jì)的佛析,使用了隨機(jī)算法痹仙,導(dǎo)致token無(wú)法進(jìn)行反向解密闷游。所以我當(dāng)初使用了redis進(jìn)行存儲(chǔ)token拜姿,前端調(diào)用API時(shí)需要攜帶token進(jìn)行身份驗(yàn)證烙样,token有效期48小時(shí)。但是我們有說(shuō)過(guò):sessionid是需要空間進(jìn)行存儲(chǔ)的砾隅,但是token在服務(wù)器是可以不需要存儲(chǔ)用戶(hù)信息的误阻。所以我們能不能做到用戶(hù)注冊(cè)登陸成功給用戶(hù)生成一個(gè)token返回給客戶(hù)端债蜜,等前端攜帶token調(diào)用API時(shí)我們直接解析token看能否解析出用戶(hù)數(shù)據(jù)來(lái)決定用戶(hù)是否有接口權(quán)限呢晴埂?事實(shí)上NodeJS提供的一個(gè)npm包:jsonwebtoken就可以實(shí)現(xiàn)token的生成與反向解密出用戶(hù)數(shù)據(jù)。接下來(lái)我們看看jsonwentoken如何進(jìn)行使用寻定。
首先先全局安裝一個(gè)express-generator儒洛,命令為:
npminstall -g express-generator
然后使用express-generator快速搭建一個(gè)express項(xiàng)目,命令為:
expressexpress_demo
然后進(jìn)入項(xiàng)目并且安裝express項(xiàng)目所需依賴(lài)狼速,命令為:
cdexpress_demo && npm install
到這里項(xiàng)目搭建成功了琅锻,我們可以看看項(xiàng)目結(jié)構(gòu):
首先在util下創(chuàng)建common.js,該文件主要放置常用公共方法向胡,這里我目前只有兩個(gè)公共方法:paramAll(用來(lái)獲取前端傳來(lái)的參數(shù))恼蓬,encryPassword(對(duì)密碼拼接字符串進(jìn)行MD5加密)。
可以看到第一行導(dǎo)入crypto依賴(lài)僵芹,MD5加密需要使用到這個(gè)包处硬,所以我們先裝下這個(gè)依賴(lài),命令為:
npminstall --save-dev crypto
然后在util下創(chuàng)建bootloader.js拇派,主要封裝幾個(gè)全局函數(shù)荷辕,用來(lái)輸出測(cè)試數(shù)據(jù)以及給前端返回?cái)?shù)據(jù)使用凿跳。
然后打開(kāi)config.js,配置jsonwebtoken生成token所需的secret疮方,secret為加密密鑰控嗜,不能泄露給其他人使用。
接下來(lái)步入正軌了骡显,我們一直說(shuō)使用jsonwebtoken生成token疆栏,那當(dāng)然我們首先安裝下jsonwebtoken巫员,命令為:
npminstall --save-dev jsonwebtoken
接下來(lái)我們來(lái)寫(xiě)個(gè)接口是線(xiàn)下token的生成月匣,我們接口實(shí)現(xiàn)在router下實(shí)現(xiàn)。首先打開(kāi)router/users.js毡鉴,在文件頂部先導(dǎo)入我們剛才編寫(xiě)的幾個(gè)文件:
接下來(lái)我們實(shí)現(xiàn)接口石挂,將用戶(hù)的基本信息結(jié)合我們?cè)O(shè)置的密鑰secret通過(guò)jsonwebtoken生成token:
通過(guò)我們剛才封裝的paramAll()進(jìn)行過(guò)去前端的傳參博助,密碼是隱私數(shù)據(jù)所以通過(guò)封裝好的encryPassword()進(jìn)行MD5加密。然后結(jié)合secret通過(guò)jsonwebtoken.sign(info, secret, options)進(jìn)行加密生成token痹愚。我們來(lái)看下接口效果:
可以看到我們成功將用戶(hù)信息轉(zhuǎn)化為token了富岳,接下來(lái)我們來(lái)看看如何反向解析出用戶(hù)數(shù)據(jù),解析token使用方法:
jsonwebtoken.verify(token,secret,callback)
我們實(shí)現(xiàn)一個(gè)接口實(shí)現(xiàn)解析用戶(hù)token獲取用戶(hù)信息:
這里需要注意的一點(diǎn):如果token解析失敗或者token已經(jīng)過(guò)期拯腮,則都會(huì)返回err窖式,只有正確解析出用戶(hù)數(shù)據(jù)才會(huì)返回data。我們可以看下效果:
可以看到我們成功把用戶(hù)數(shù)據(jù)解析出來(lái)动壤,接下來(lái)我們可以看看在真正的API接口中我們?nèi)绾稳ナ褂?b>jsonwebtoken去進(jìn)行token的解析使用萝喘。首先我們提到過(guò)了接口安全性一般要使用簽名,簽名規(guī)則還是依舊使用我一直使用的規(guī)則:
1.將接口所需參數(shù)加上當(dāng)前時(shí)間戳參數(shù)time琼懊,time取毫秒值組裝成json對(duì)象阁簸。
2.將所有參數(shù)以key=value的形式按照ASCII的順序進(jìn)行排序得到waitSign。
3.對(duì)waitSign進(jìn)行MD5加密哼丈,得到signParam.
4.將signParam轉(zhuǎn)化為純小寫(xiě)启妹,得到最終的簽名sign。
那接下來(lái)我們首先先把生成簽名的算法封裝成公共方法放到common.js中:
API接口免不了數(shù)據(jù)庫(kù)操作醉旦,我們接下來(lái)封裝下數(shù)據(jù)庫(kù)操作饶米。首先在config.js中配置數(shù)據(jù)庫(kù)配置信息:
接下來(lái)在項(xiàng)目根目錄創(chuàng)建db文件夾,在db下創(chuàng)建mysql.js對(duì)數(shù)據(jù)庫(kù)的增刪改查操作進(jìn)行封裝车胡,先封裝連接池初始化以及連接池釋放方法:
再封裝一個(gè)用戶(hù)插入更新數(shù)據(jù)檬输,一個(gè)用于查詢(xún)數(shù)據(jù):
到這里數(shù)據(jù)庫(kù)我們也封裝好了,我們開(kāi)始寫(xiě)API實(shí)現(xiàn)用戶(hù)登陸匈棘,登陸成功生成token丧慈。我們看看實(shí)現(xiàn)的代碼:
其實(shí)登陸邏輯可以分為三個(gè)步驟:
1.將參數(shù)按照解密規(guī)則加密生成簽名sign
2.簽名驗(yàn)證成功,數(shù)據(jù)庫(kù)驗(yàn)證賬號(hào)密碼是否匹配3.賬號(hào)密碼匹配生成token與用戶(hù)信息一起返回給前端
我將數(shù)據(jù)庫(kù)操作封裝到dao層下的users.js下羹饰,我們看下登陸數(shù)據(jù)庫(kù)的邏輯代碼:
到這里登陸邏輯完成了伊滋,我們看下接口的調(diào)用效果:
調(diào)用成功碳却,會(huì)生成一個(gè)token結(jié)合用戶(hù)信息一起返回給前端。我們?cè)賹?shí)現(xiàn)一個(gè)接口查詢(xún)用戶(hù)個(gè)人積分信息笑旺。前端調(diào)用API需要攜帶token進(jìn)行驗(yàn)證個(gè)人信息昼浦。
本接口一樣分成三個(gè)步驟:
1.將參數(shù)按照解密規(guī)則加密生成簽名sign
2.簽名驗(yàn)證成功,解析token驗(yàn)證解析后的用戶(hù)賬號(hào)與用戶(hù)傳參的賬號(hào)是否一致
3.驗(yàn)證成功進(jìn)行數(shù)據(jù)庫(kù)操作查詢(xún)用戶(hù)的積分?jǐn)?shù)據(jù)返回給前端
一樣我們把數(shù)據(jù)庫(kù)操作封裝在dao/users.js下筒主,我們可以看下數(shù)據(jù)庫(kù)邏輯:
我們看下接口調(diào)用效果:
可以看到我們成功解析token獲得用戶(hù)信息关噪,并查詢(xún)到用戶(hù)的積分信息。
其實(shí)在公司前后端交互基本上我們也是采用簽名sign?+?token + timestamp的驗(yàn)證方式乌妙。本篇文章也完成的重現(xiàn)了開(kāi)發(fā)接口的整個(gè)流程使兔,為了提高代碼可維護(hù)性,我們將一些公共方法全部進(jìn)行了封裝藤韵,為后續(xù)的產(chǎn)品迭代增加了更多的可能性虐沥。
本篇文章源碼以及上篇加解密算法源碼已上傳碼云,下載鏈接:
https://gitee.com/mqzuimeng/test_code.git
????????如果喜歡我的文章泽艘,歡迎關(guān)注我的個(gè)人公眾號(hào):周先生自留地欲险。
推薦閱讀