在領(lǐng)取了學(xué)習(xí)一期源碼權(quán)限控制邏輯學(xué)習(xí)這張卡之后,一切進(jìn)展都挺順利的,就在我以為一切都結(jié)束了,將我對這個權(quán)限控制的理解寫成簡書之后,提交給老師QA時,老師提出了一個問題:在邏輯控制中角色與API接口的關(guān)系是什么?
首先我看到這問題想到的是:角色只有兩種,分為學(xué)生和管理員;API那么也應(yīng)該分為兩種一種是對學(xué)生使用的API,一種是對管理員使用的API。
然后我又想代碼里邊不是都寫了API的訪問邏輯了,為什么還要去研究這個問題。懷揣這這個問題,我又去請教了一次林老師,林老師的回答是:如果一個學(xué)生他知道了我們的管理員這邊的API,使用network發(fā)送了管理員接口的請求時,如果沒有這個邏輯關(guān)系的判斷,那么我們的系統(tǒng)就有風(fēng)險(xiǎn)了。聽了這個回答之后我才恍然大悟,還是我的思考太局限了。。。扯了這么多了,開始說正題吧!這個角色與API接口之間的關(guān)系到底是如何控制的呢?
看到這個問題,我的第一反應(yīng)是在每個API里都有一個判斷語句,看這個請求是否正確(就是這個請求的發(fā)送者是否有權(quán)限去發(fā)送這個請求,這個請求是否可以被處理)。然后有這個思路我就先去找了管理員這邊的API去看,然后發(fā)現(xiàn)并沒有這個邏輯判斷,所以,這種方案失敗!
那就換個思路吧!
在每一次請求發(fā)送之后,首先都會經(jīng)過app.js
這個文件,所以有沒有可能是在這里邊處理的呢?
果然,在這個文件里邊,加載了這樣一個中間件app.use(checkSession);
,這個中間件是由check-session.js
這個文件exports的,該文件源碼為:
var getJumpControl = require('../mixin/jump-control');
function getType (o) {
var typeStr = Object.prototype.toString.call(o).slice(8, -1);
return typeStr;
}
function matchUrl (url, patterns) { return patterns.some((pattern) => {
if (getType(pattern) === 'RegExp') {
return pattern.test(url);
} else {
return url.indexOf(pattern) > -1;
}
});
}
function pathControl (url, session) {
var target = {};
var needRedirect = false;
var jumpControl = getJumpControl(session);
jumpControl.forEach((item) => {
if (matchUrl(url, item.originPath) && item.condition) {
target = item;
needRedirect = true;
return;
}
});
return {
needRedirect: needRedirect,
status: target.status
};
}
module.exports = function (req, res, next) {
var target = pathControl(req.url, req.session);
if (target.needRedirect) {
res.sendStatus(target.status);
} else {
next();
}
};
這個文件里邊引入了getJumpControl
這個方法,這個方法的源碼為:
/*getJumpControl源碼*/
function jumpControl (session) {
var isLogined = Boolean(session.user);
var isAdmin = isLogined ? (Number(session.user.role) === 9) : false;
return [{
originPath: [
'/reuse/account',
/homework\/scoring$/
],
condition: !isLogined,
status: 401
}, {
originPath: [
'/admin/registerable',
'/admin/channel',
'/report/paper/1/scoresheet'
],
condition: !isLogined || !isAdmin,
status: 403
}];
}
module.exports = jumpControl;
因?yàn)樵诿恳淮蔚卿浿螅紩⒂脩舻乃行畔⒋嫒氘?dāng)前的session.user中,然后當(dāng)有一個請求發(fā)送過來之后,就會使用session中的數(shù)據(jù),輔助check-session.js的判斷,如果API與用戶的關(guān)系符合規(guī)則,那么needRedirect
這個屬性值為false,并將該請求發(fā)送,若判斷不符合規(guī)則,needRedirect
這個屬性值為true,并將請求終止,send對應(yīng)的httpCode。
這就是我理解的角色與API接口之間的關(guān)系!
問題解決了!
個人總結(jié):
問題雖然成功解決,但是花費(fèi)時間過長,總結(jié)原因,還是由于我考慮這個問題時,考慮的不夠深刻,不夠仔細(xì),導(dǎo)致方向走錯,最終花費(fèi)時間太多!
吸取教訓(xùn),加油!