文章目錄
- 1. 資料庫創建
- 2. 創建一個thinkjs專案
- 3. 配置專案資料庫
- 4. 用戶的登錄驗證實作
1. 資料庫創建
用Navicat創建一個資料庫“db”,在創建一張存盤用戶登錄資訊的表,命名為“demo-admin”,
表的設計如下(表直接拿“hioshop”開源專案中的admin表):
hioshop-server
| id | username | password | password_salt | last_login_ip | last_login_time | is_delete |
|---|---|---|---|---|---|---|
| 14 | hiolabs | 4af5d2d0e6c2bd03dca28c884afdf0ee | HIOLABS |
2. 創建一個thinkjs專案
thinkjs new demo-server//創建一個thinkjs專案
3. 配置專案資料庫
找到專案‘src/config/adapter.js’檔案,打開這個檔案,修改代碼如下:
mysql: {
handle: mysql,//mysql資料庫
database: 'db',//資料庫名
prefix: 'demo_',//資料表前綴,如果一個資料庫里有多個專案,那專案之間的資料表可以通過前綴來區分
encoding: 'utf8mb4',//資料庫編碼方式
host: '127.0.0.1',//主機ip
port: '3306',//埠號
user: 'root',//用戶名
password: '123123123',//密碼
dateStrings: true
}
4. 用戶的登錄驗證實作
//創建一個"auth.js"的controller控制器
thinkjs controller auth
//創建一個"token.js"的Service物件,用來定義token驗證的相關方法
thinkjs service token
假設客戶端向服務端發送一個post請求攜帶用戶名和密碼的請求‘/auth/login’介面,服務端對當前
請求進行驗證,驗證通過則往下繼續執行,相關驗證代碼如下:
//"auth.js"
const Base = require('./base.js');
module.exports = class extends Base {
async loginAction(){//登錄驗證
//獲取前端提交過來的用戶名,并定義一個常量存盤它
const username = this.post('username');
//獲取前端提交過來的密碼,并定義一個常量存盤它
const password = this.post('password');
//對用戶名進行驗證
const admin = await this.model('admin').where({username:username}).find();
if(think.isEmpty(admin)){
return this.fail(401,'用戶名不正確');
}
//對用戶密碼進行驗證
if(think.md5(password + '' + admin.password_salt) !== admin.password){
return this.fail(401,'用戶密碼錯誤');
}
//用戶名和密碼都正確的話,更新當前用戶的登錄時間和登錄ip到記錄對應的資料表相應欄位中
await this.model('admin').where({id:admin.id}).update({
last_login_time:parseInt(Date.now()/1000),
last_login_ip:this.ctx.ip
});
//實體化一個tokenservice物件,來呼叫create()方法創建一個token
const TokenService = this.service('token');
const token = await TokenService.create({
id:admin.id//payload
});
//判斷token是否創建成功
if(think.isEmpty(token)){
return this.fail('用戶登錄失敗');
}
//令牌創建成功,回傳給客戶端"uerInfo"和"token"給前端
const userInfo = {
id:admin.id,
username:admin.username
};
return this.success({
token:token,
userInfo:userInfo
});
}
};
//"token.js"
const jwt = require('jsonwebtoken');//JWT
const secret = '&w@ueJnXy!Gj0J@qVmMPR^9ip00EP0^Qy5Se#lzwStExJ3Zw4j02NVLm^btjBO8x'
module.exports = class extends think.Service {
async create(userId){//創建令牌
const token = jwt.sign(userId,secret);
return token;
}
async parse(){//令牌驗簽
if(think.isEmpty(think.token)){//如果token為空
return null;
}
else{
try{
return jwt.verify(think.token,secret).id;
}catch(err){
return null;
}
}
}
};
通過以上操作后端介面‘auth/login’將token回傳給客戶端,假設客戶端獲取到服務端回應的token,
把token值存盤在header請求頭'Authorization'中,便于每次請求路由時攜帶token發送到服務端
接著實作對每次請求的token驗證是否合法的實作,代碼如下:
//base.js
module.exports = class extends think.Controller {
async _before(){//_before()方法在訪問每條路由前都會先執行此函式
//從客戶端請求頭header中獲取發送過來的token,如果沒有獲取到給think.token賦空值
think.token = this.ctx.header['Authorization'] || '';
//宣告一個Token實體來呼叫token.js里的parse()方法來對token進行驗簽,通過則回傳用戶ID,失敗回傳null
const Token = this.service('token');
think.userId = await Token.parse();
if(this.ctx.controller !== 'auth'){//如果當前路由不是'/auth'且
if(think.isEmpty(think.userId)){//如果用戶ID為空
return this.fail('用戶未登錄');
}
}
}
};
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/223240.html
標籤:其他
