調(diào)用后端接口怎么樣才安全芬迄?

  • 在APP中保存登錄數(shù)據(jù)问顷,每次調(diào)用接口時(shí)傳輸

程序員總能給自己找到偷懶的方法,有的程序?yàn)榱耸∈拢瑫?huì)在用戶登錄后杜窄,直接把用戶名和密碼保存在本地肠骆,然后每次調(diào)用后端接口時(shí)作為參數(shù)傳遞。真省事兒叭蚀腿!可這種方法簡(jiǎn)單就像拿著一袋子錢在路上邊走邊喊“快來(lái)?yè)屛已剑】靵?lái)?yè)屛已缴ㄍ猓 蔽ㄒВ粋€(gè)小小的嗅探器就能把用戶的密碼拿到手,如果用戶習(xí)慣在所有地方用一個(gè)密碼畏浆,那么你闖大禍了胆胰,黑客通過(guò)撞庫(kù)的方法能把用戶的所有信息一鍋端。

  • 登錄時(shí)請(qǐng)求一次token刻获,之后用token調(diào)用接口

這是比較安全的方式蜀涨,用戶在登錄時(shí),APP調(diào)用獲取token的接口(比如http://api.abc.com/get_token/)蝎毡,用post將用戶名和密碼的摘要傳遞給服務(wù)器厚柳,然后服務(wù)器比對(duì)數(shù)據(jù)庫(kù)中的用戶信息,匹配則返回綁定該用戶的token(這一般翻譯為令牌沐兵,很直觀的名字别垮,一看就知道是有了這玩意,就會(huì)對(duì)你放行)扎谎,而數(shù)據(jù)庫(kù)中碳想,在用戶的token表中也同時(shí)插入了這個(gè)token相關(guān)的數(shù)據(jù):這個(gè)token屬于誰(shuí)?這個(gè)token的有效期是多久毁靶?這個(gè)token當(dāng)前登錄的ip地址是胧奔?這個(gè)token對(duì)應(yīng)的deviceid是?……
這樣即便token被有心人截獲预吆,也不會(huì)造成太大的安全風(fēng)險(xiǎn)龙填。因?yàn)闆](méi)有用戶名和密碼,然后如果黑客通過(guò)這個(gè)token偽造用戶請(qǐng)求拐叉,我們?cè)诜?wù)器端接口被調(diào)用時(shí)就可以對(duì)發(fā)起請(qǐng)求的ip地址岩遗、user-agent之類的信息作比對(duì),以防止偽造凤瘦。再然后宿礁,如果token的有效期設(shè)得小,過(guò)一會(huì)兒它就過(guò)期了廷粒,除非黑客可以持續(xù)截獲你的token窘拯,否則他只能干瞪眼。(插一句題外話:看到這里坝茎,是不是明白為什么不推薦在外面隨便接入來(lái)歷不明的wifi熱點(diǎn)了涤姊?)
tips:token如何生成? 可以根據(jù)用戶的信息及一些隨機(jī)信息(比如時(shí)間戳)再通過(guò)hash編碼(比如md5嗤放、sha1等)生成唯一的編碼思喊。
tips:token的安全級(jí)別,取決于你的實(shí)際需求次酌,所以如果不是涉及財(cái)產(chǎn)安全的領(lǐng)域恨课,并不建議太嚴(yán)格(比如用戶走著走著,3G換了個(gè)基站岳服,閃斷了一下IP地址變了剂公,尼瑪token過(guò)期了,這就屬于為了不必要的安全丟了用戶體驗(yàn)吊宋,當(dāng)然如果變換的IP地址跨省的話還是應(yīng)該驗(yàn)證一下的纲辽,想想QQ有時(shí)候會(huì)讓填驗(yàn)證碼就明白了)。
tips:接口在返回信息時(shí)璃搜,可以包含本次請(qǐng)求的狀態(tài)拖吼,比如成功調(diào)用,那么result['status']可能就是'success'这吻,而反之則是'error'吊档,而如果是'error',則result['errcode']中就可以包含錯(cuò)誤的原因唾糯,比如errcode中是'invalid_token'就可以告訴APP這個(gè)token過(guò)期或無(wú)效怠硼,這時(shí)APP應(yīng)彈出登錄框或者用本地存儲(chǔ)的用戶名或密碼再次請(qǐng)求token(用戶選擇“記住密碼”,就應(yīng)該在本地保存用戶名和密碼的摘要移怯,方法見(jiàn)plus.storage的文檔)拒名。

再插點(diǎn)代碼,基于plus.storage的用戶信息類芋酌,注意:需要在plusReady之后再使用增显。

function UserInfo(){
};

//清除登錄信息
UserInfo.clear = function(){
    plus.storage.removeItem('username');
    plus.storage.removeItem('password');
    plus.storage.removeItem('token');
}

//檢查是否包含自動(dòng)登錄的信息
UserInfo.auto_login = function(){
    var username = UserInfo.username();
    var pwd = UserInfo.password();
    if(!username || !pwd){
        return false;
    }
    return true;
}

//檢查是否已登錄
UserInfo.has_login = function(){
    var username = UserInfo.username();
    var pwd = UserInfo.password();
    var token = UserInfo.token();
    if(!username || !pwd || !token){
        return false;
    }
    return true;
};

UserInfo.username = function(){
    if(arguments.length == 0){
        return plus.storage.getItem('username');        
    }
    if(arguments[0] === ''){
        plus.storage.removeItem('username');
        return;
    }
    plus.storage.setItem('username', arguments[0]);
};

UserInfo.password = function(){
    if(arguments.length == 0){
        return plus.storage.getItem('password');        
    }
    if(arguments[0] === ''){
        plus.storage.removeItem('password');
        return;
    }
    plus.storage.setItem('password', arguments[0]);
};

UserInfo.token = function(){
    if(arguments.length == 0){
        return plus.storage.getItem('token');       
    }
    if(arguments[0] === ''){
        plus.storage.removeItem('token');
        return;
    }
    plus.storage.setItem('token', arguments[0]);
};

這樣當(dāng)用戶啟動(dòng)APP或使用了需要登錄才能使用的功能時(shí),就可以使用UserInfo.has_login()來(lái)判斷是否已經(jīng)登錄脐帝,如果已登錄同云,則使用UserInfo.token()來(lái)獲取到token數(shù)據(jù),作為參數(shù)調(diào)用遠(yuǎn)程的后端接口堵腹。

if(UserInfo.has_login()){
    //打開(kāi)需要展示給用戶的頁(yè)面炸站,或者是調(diào)用遠(yuǎn)端接口
}
else{
    wv_login.show('slide-in-up');   //從底部向上滑出登錄頁(yè)面
}

在登錄頁(yè)面中,用戶輸入了用戶名和密碼后疚顷,并點(diǎn)擊了”登錄“按鈕旱易,我們下一步做什么禁偎?再插段代碼(注意:此處使用的是我剛才代碼中擴(kuò)展的web_query函數(shù),你也可以直接使用mui的ajax):

function get_pwd_hash(pwd){
    var salt = 'hbuilder';  //此處的salt是為了避免黑客撞庫(kù)阀坏,而在md5之前對(duì)原文做一定的變形如暖,可以設(shè)為自己喜歡的,只要和服務(wù)器驗(yàn)證時(shí)的salt一致即可忌堂。
    return md5(salt + pwd); //此處假設(shè)你已經(jīng)引用了md5相關(guān)的庫(kù)盒至,比如github上的JavaScript-MD5
}

//這里假設(shè)你已經(jīng)通過(guò)DOM操作獲取到了用戶名和密碼,分別保存在username和password變量中士修。
var username = xxx;
var password = xxx;
var pwd_hash = get_pwd_hash(password);

var onSuccess = function(data){
    UserInfo.username(username);
    UserInfo.password(pwd_hash);
    UserInfo.token(data.token); //把獲取到的token保存到storage中
    var wc = plus.webview.currentWebview();
    wc.hide('slide-out-bottom');    //此處假設(shè)是隱藏登錄頁(yè)回到之前的頁(yè)面枷遂,實(shí)際你也可以干點(diǎn)兒別的
}

var onError = function(errcode){
    switch(errcode){
    case 'INCORRECT_PASSWORD':
        mui.toast('密碼不正確');
        break;
    case 'USER_NOT_EXISTS':
        mui.toast('用戶尚未注冊(cè)');
        break;
    }
}

mui.web_query('get_token', {username:username,password:pwd_hash}, onSuccess, onError, 3);
  • 更安全一點(diǎn),獲取token通過(guò)SSL

剛才的方法棋嘲,機(jī)智一點(diǎn)兒的讀者大概會(huì)心存疑慮:那獲取token時(shí)不還是得明文傳輸一次密碼嗎酒唉?
是的,你可以將這個(gè)獲取token的地址沸移,用SSL來(lái)保護(hù)(比如https://api.abc.com/get_token/)黔州,這樣黑客即使截了包,一時(shí)半會(huì)兒也解不出什么信息阔籽。
SSL證書的獲取渠道很多流妻,我相信你總有辦法查到,所以不廢話了笆制。不過(guò)話說(shuō)namecheap上的SSL證書比godaddy的要便宜得多……(這是吐槽)
tips:前段時(shí)間OpenSSL漏洞讓很多服務(wù)器遭殃绅这,所以如果自己搭服務(wù)器,一定記得裝補(bǔ)丁在辆。
tips:可以把所有接口都弄成SSL的嗎证薇?可以。但會(huì)拖慢服務(wù)器匆篓,如果是配置并不自信的VPS浑度,建議不折騰。

  • 還要更更安全(這標(biāo)題真省事)

還記得剛才APP向服務(wù)器請(qǐng)求token時(shí)鸦概,可以加入的用戶信息嗎箩张?比如用戶的設(shè)備deviceid。
如果我們?cè)谡{(diào)用接口時(shí)窗市,還附帶一個(gè)當(dāng)前時(shí)間戳參數(shù)timestamp先慷,同時(shí),用deviceid和這個(gè)時(shí)間戳再生成一個(gè)參數(shù)sign咨察,比如 md5(deviceid timestamp token)這樣的形式论熙。而服務(wù)端首先驗(yàn)證一下參數(shù)中的時(shí)間戳與當(dāng)前服務(wù)器時(shí)間是否一致(誤差保持在合理范圍內(nèi)即可,比如5分鐘)摄狱,然后根據(jù)用戶保存在服務(wù)器中的deviceid來(lái)對(duì)參數(shù)中的時(shí)間戳進(jìn)行相同的變形脓诡,驗(yàn)證是否匹配无午,那便自然“更更安全”了。
tips:如果對(duì)整個(gè)調(diào)用請(qǐng)求中的參數(shù)進(jìn)行排序祝谚,再以deviceid和timestamp加上排序后的參數(shù)來(lái)對(duì)整個(gè)調(diào)用生成1個(gè)sign宪迟,黑客即使截獲sign,不同的時(shí)間點(diǎn)踊跟、參數(shù)請(qǐng)求所使用的sign也是不同的踩验,難以偽造鸥诽,自然會(huì)更安全商玫。當(dāng)然,寫起來(lái)也更費(fèi)事牡借。

原文地址:http://ask.dcloud.net.cn/article/157

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末拳昌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子钠龙,更是在濱河造成了極大的恐慌炬藤,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件碴里,死亡現(xiàn)場(chǎng)離奇詭異沈矿,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)咬腋,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門羹膳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人根竿,你說(shuō)我怎么就攤上這事陵像。” “怎么了寇壳?”我有些...
    開(kāi)封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵醒颖,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我壳炎,道長(zhǎng)泞歉,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任匿辩,我火速辦了婚禮疏日,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘撒汉。我一直安慰自己沟优,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開(kāi)白布睬辐。 她就那樣靜靜地躺著挠阁,像睡著了一般宾肺。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上侵俗,一...
    開(kāi)封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天锨用,我揣著相機(jī)與錄音,去河邊找鬼隘谣。 笑死增拥,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的寻歧。 我是一名探鬼主播掌栅,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼码泛!你這毒婦竟也來(lái)了猾封?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤噪珊,失蹤者是張志新(化名)和其女友劉穎晌缘,沒(méi)想到半個(gè)月后痢站,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體磷箕,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年阵难,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了岳枷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡多望,死狀恐怖怀偷,靈堂內(nèi)的尸體忽然破棺而出椎工,到底是詐尸還是另有隱情掰吕,我是刑警寧澤,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布斑响,位于F島的核電站,受9級(jí)特大地震影響薛耻,放射性物質(zhì)發(fā)生泄漏蝙搔。R本人自食惡果不足惜杂瘸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一伙菊、第九天 我趴在偏房一處隱蔽的房頂上張望败玉。 院中可真熱鬧运翼,春花似錦、人聲如沸财剖。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)买鸽。三九已至,卻和暖如春贯被,著一層夾襖步出監(jiān)牢的瞬間眼五,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工彤灶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留看幼,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓幌陕,卻偏偏與公主長(zhǎng)得像诵姜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子搏熄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

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