前端文件下載的權(quán)限驗(yàn)證問(wèn)題

問(wèn)題介紹

在前后端分離的模式下徒扶,如果前端希望從后端下載一個(gè)文件氛赐,通常的做法是后端通過(guò)一個(gè)接口返回給前端一個(gè)下載的地址,然后前端模擬瀏覽器的點(diǎn)擊事件或者調(diào)用window.open來(lái)實(shí)現(xiàn)文件的下載。

但是在通常情況下佛析,后端的接口都會(huì)需要權(quán)限驗(yàn)證栗精,比如要在header中添加Authorization的頭闯参,但是由于使用上述方法提到的文件下載方式并沒(méi)有使用ajax請(qǐng)求,所以我們并不能簡(jiǎn)單的在header中添加權(quán)限驗(yàn)證的頭悲立。

所以鹿寨,后端僅僅返回一個(gè)下載地址供前端下載的方式是不安全的,任何獲取到該url的人都能夠輕易的得到下載內(nèi)容薪夕。

解決方案

這里介紹兩種解決的方法脚草。

  1. 依賴于jwt的機(jī)制,使得文件下載的url需要在query中添加token參數(shù)進(jìn)行權(quán)限驗(yàn)證
  2. 利用 HTML5 File API原献。使用createObjectURL玩讳,revokeObjectURL方法來(lái)創(chuàng)建和下載文件涩蜘,從而可以利用ajax來(lái)模擬實(shí)現(xiàn)文件下載。

基于jwt實(shí)現(xiàn)權(quán)限驗(yàn)證

例如下載地址為 /download/fileA

  1. 后端需要額外提供一個(gè)接口供用戶獲取下載用的token
  2. 客戶端使用ajax請(qǐng)求該接口獲取token
  3. 客戶端模擬打開(kāi)拼接了token的url:/download/fileA?token=xxx
  4. 后端解析該token判斷用戶是否有權(quán)限下載該文件
// 服務(wù)器端
const jwt = require('jsonwebtoken');
...
router.get('/download/token', (req, res) => {
  const secret = 'xxxxxx'
  const token = jwt.sign({}, secret, { expiresIn: 2 }); // 2s內(nèi)有效
  return res.json({ token });
});

// 客戶端
const download = async (url) => {
const { data: { token } } = await axios.get('/download/token');
let finalUrl = url;
if (url.includes('?')) {
 finalUrl += `&token=${token}`;
} else {
 finalUrl += `?token=${token}`;
}
window.open(finalUrl);
}

// 服務(wù)器端具體解析token下載文件的代碼就省略了熏纯。
// jwt的使用參考jsonwebtoken庫(kù)的使用

利用 HTML5 File API 實(shí)現(xiàn)權(quán)限驗(yàn)證

  1. 后端提供文件下載的接口與其他接口保證同樣的權(quán)限驗(yàn)證策略同诫,例如在header中驗(yàn)證Authorization頭
  2. 前端使用ajax請(qǐng)求文件下載的接口
  3. 前端利用window.URL.createObjectURL將請(qǐng)求得到的內(nèi)容轉(zhuǎn)化為objectUrl
  4. 前端模擬點(diǎn)擊,使用window.URL.revokeObjectURL(url)實(shí)現(xiàn)文件下載
// 客戶端
const download = async (url) => {
  const response = await axios.get('/download/fileA', {headers: {Authorization: 'Token xxxxxx'}});
  const blob = new Blob([response], { type: 'text/plain;charset=utf-8' });
  const url = window.URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = url;
  a.download = [fileName];
  a.click();
  window.URL.revokeObjectURL(url);
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末樟澜,一起剝皮案震驚了整個(gè)濱河市误窖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌秩贰,老刑警劉巖霹俺,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異毒费,居然都是意外死亡丙唧,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)觅玻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)想际,“玉大人,你說(shuō)我怎么就攤上這事溪厘『荆” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵畸悬,是天一觀的道長(zhǎng)侧甫。 經(jīng)常有香客問(wèn)我,道長(zhǎng)蹋宦,這世上最難降的妖魔是什么披粟? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮冷冗,結(jié)果婚禮上守屉,老公的妹妹穿的比我還像新娘。我一直安慰自己贾惦,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布敦捧。 她就那樣靜靜地躺著须板,像睡著了一般。 火紅的嫁衣襯著肌膚如雪兢卵。 梳的紋絲不亂的頭發(fā)上习瑰,一...
    開(kāi)封第一講書(shū)人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音秽荤,去河邊找鬼甜奄。 笑死柠横,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的课兄。 我是一名探鬼主播牍氛,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼烟阐!你這毒婦竟也來(lái)了搬俊?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤蜒茄,失蹤者是張志新(化名)和其女友劉穎唉擂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體檀葛,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡玩祟,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屿聋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片空扎。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖胜臊,靈堂內(nèi)的尸體忽然破棺而出勺卢,到底是詐尸還是另有隱情,我是刑警寧澤象对,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布黑忱,位于F島的核電站,受9級(jí)特大地震影響勒魔,放射性物質(zhì)發(fā)生泄漏甫煞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一冠绢、第九天 我趴在偏房一處隱蔽的房頂上張望抚吠。 院中可真熱鬧,春花似錦弟胀、人聲如沸楷力。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)萧朝。三九已至,卻和暖如春夏哭,著一層夾襖步出監(jiān)牢的瞬間检柬,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工竖配, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留何址,地道東北人里逆。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像用爪,于是被迫代替她去往敵國(guó)和親原押。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,180評(píng)論 25 707
  • 今天项钮,將由凱瑟琳化妝總監(jiān)豆豆老師帶您一起了解何為好婚紗 設(shè)計(jì)的極致是好婚紗的終極歸宿班眯。設(shè)計(jì)說(shuō)起來(lái)是一個(gè)是抽象的...
    凱瑟琳造型師豆豆閱讀 513評(píng)論 0 0
  • 筆記本依舊 殘存著無(wú)法回答的答案 我的手心 似乎還有你未寫(xiě)完的筆跡 我抬頭 似乎看到我們?cè)谙嗤?你是誰(shuí) 我又是誰(shuí) ...
    言由衷閱讀 125評(píng)論 0 0
  • 近日身體不太好,恍恍惚惚烁巫,做了兩個(gè)如第一人稱游戲一般的夢(mèng): 偵探與犯罪 限時(shí)救援 《偵探與犯罪》署隘,開(kāi)篇(第一階段)...
    之乎閱讀 201評(píng)論 0 1
  • 《四十千》講了一個(gè)幼兒夭折的悲劇。 在明末的嬰幼兒死亡率背景下亚隙,貌似很正常磁餐,但仔細(xì)算一下賬就發(fā)現(xiàn)不對(duì)了。 原文開(kāi)頭...
    覺(jué)史氏閱讀 883評(píng)論 0 1