最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Angular.js與node.js項(xiàng)目里用cookie校驗(yàn)賬戶登錄詳解

 更新時(shí)間:2017年02月22日 10:07:06   作者:xishiyi7  
這篇文章主要介紹了Angular.js與node.js項(xiàng)目里用cookie校驗(yàn)賬戶登錄的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。

前言

最近的新項(xiàng)目中,用戶登錄需要采用cookie來(lái)記住用戶,校驗(yàn)身份。所以本文就把實(shí)現(xiàn)的過(guò)程總結(jié)出來(lái)分享給大家,需要的朋友們可以參考學(xué)習(xí)。

在header中攜帶authId登錄

在之前老的項(xiàng)目里,沒(méi)有采用cookie來(lái)記錄用戶登錄狀態(tài),而是在請(qǐng)求的header中攜帶一個(gè)身份標(biāo)識(shí)來(lái)校驗(yàn),大致方案如下:

  1. 客戶端使用post請(qǐng)求提交user、password給服務(wù)端進(jìn)行登錄操作;
  2. 服務(wù)端校驗(yàn)用戶是否合法,如果合法將產(chǎn)生一個(gè)唯一的身份標(biāo)識(shí)authId,返回給客戶端,客戶端將此authId存放本地(如localStorage);
  3. 客戶端在每次需要校驗(yàn)身份的請(qǐng)求中,往header中加入這個(gè)authId;
  4. 服務(wù)端檢測(cè)當(dāng)前的authId是否有效,有效則表示當(dāng)前用戶合法,允許操作;
  5. 客戶端用戶登出的時(shí)候,發(fā)送一個(gè)delete請(qǐng)求,告訴服務(wù)端用戶注銷(xiāo),同時(shí)刪除本地的authId信息;
  6. 服務(wù)端收到注銷(xiāo)請(qǐng)求后,刪除當(dāng)前的authId數(shù)據(jù)。

上面的方案,如果其他客戶端知道了這個(gè)authId后,可以在其他客戶端模擬身份,不安全,因此棄用。

用cookie記住用戶

新項(xiàng)目中,將采用此文即將介紹的方案–利用cookie來(lái)記住用戶。主要流程是:

  1. 客戶端使用post請(qǐng)求提交user、password給服務(wù)端進(jìn)行登錄操作;
  2. 服務(wù)端校驗(yàn)用戶是否合法,如果合法將產(chǎn)生一個(gè)唯一的身份標(biāo)識(shí)authId,以cookie的形式返回給客戶端;
  3. 客戶端再次請(qǐng)求服務(wù)端時(shí),會(huì)攜帶此前已經(jīng)拿到的cookie給服務(wù)端,服務(wù)端校驗(yàn)是否合法,合法則可以繼續(xù)操作;
  4. 客戶端用戶登出的時(shí)候,發(fā)送一個(gè)delete請(qǐng)求,告訴服務(wù)端用戶注銷(xiāo),服務(wù)端刪除登錄標(biāo)識(shí)。

     整個(gè)過(guò)程可以用下面這張圖簡(jiǎn)單表示:


前臺(tái)用angular搭建單頁(yè)客戶端應(yīng)用,后臺(tái)用node搭建服務(wù)器,數(shù)據(jù)存放在mongodb中,這三個(gè)技術(shù)及cookie基礎(chǔ)知識(shí)本文不做介紹,感興趣的同學(xué)可以自行了解。

以下的代碼都是最簡(jiǎn)單的get/post請(qǐng)求,但也是最核心的部分,其他有關(guān)登錄的繁瑣操作,感興趣的同學(xué)可以自行補(bǔ)充。

從開(kāi)始–>結(jié)束,遇到的問(wèn)題

首先,我用的是最基礎(chǔ)的post請(qǐng)求,服務(wù)端也只是簡(jiǎn)單的返回?cái)?shù)據(jù),部分簡(jiǎn)單但比較核心的代碼如下:

// client
$http({
 method   : 'POST',
 url   : 'http://127.0.0.1:8888/rest/user',
 data   : {name: 'xxx',password:'***'}
 }).success(function (data) {
 console.log('login success,data is:'+data);
}).error(function (data) {
 console.log('login error');
}).then(function () {
 console.log(arguments);
});

// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();

查看chrome調(diào)試,發(fā)現(xiàn)雖然服務(wù)端的cookie推過(guò)來(lái)了,但整體出了問(wèn)題,提示如下:

XMLHttpRequest cannot load http://127.0.0.1:8888/rest/user. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:62427' is therefore not allowed access.

分析問(wèn)題后,發(fā)現(xiàn)原因是來(lái)自客戶端的請(qǐng)求不能跨域訪問(wèn)服務(wù)端的請(qǐng)求,請(qǐng)求的資源header中沒(méi)有攜帶允許跨越請(qǐng)求的信息。根據(jù)這個(gè)提示,我們把服務(wù)端的代碼稍加改進(jìn)后,如下:

// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');

// 添加允許跨越的頭信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');

res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();

解釋下上面代碼什么意思,第一句主要是允許來(lái)自任何域的請(qǐng)求訪問(wèn),第二句是允許哪些類(lèi)型的請(qǐng)求訪問(wèn)。加上后再次運(yùn)行,提示如下:

XMLHttpRequest

cannot load http://127.0.0.1:8888/rest/user. Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response.

原因是來(lái)自客戶端的請(qǐng)求中,Content-Type頭字段,在服務(wù)端的響應(yīng)信息的頭中,沒(méi)有攜帶,再次修改代碼如下:

// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');

// 添加允許跨越的頭信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');

// 添加支持Content-Type允許的頭信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();

再次運(yùn)行代碼,發(fā)現(xiàn)沒(méi)有錯(cuò)誤提示,但是當(dāng)我們?cè)俅握?qǐng)求服務(wù)器時(shí),發(fā)現(xiàn)客戶端的請(qǐng)求并沒(méi)有攜帶cookie信息,這顯然不是我們想要的效果:

在查閱了一段時(shí)間后了解到,客戶端是會(huì)默認(rèn)攜帶cookie給服務(wù)端的,但是當(dāng)客戶端的請(qǐng)求是跨域請(qǐng)求時(shí),由于跨域請(qǐng)求本身就有風(fēng)險(xiǎn),而攜帶給cookie同樣有風(fēng)險(xiǎn)。

因此在進(jìn)行跨域訪問(wèn)時(shí),客戶端不會(huì)將服務(wù)端返回的cookie攜帶。此時(shí),我們需要同時(shí)在客戶端和服務(wù)端都設(shè)置“withCredentials”為true,代碼如下:

// client
$http({
 method   : 'POST',
 url   : 'http://127.0.0.1:8888/rest/user',
 withCredentials: true
 data   : {name: 'xxx',password:'***'}
 }).success(function (data) {
 console.log('login success,data is:'+data);
}).error(function (data) {
 console.log('login error');
}).then(function () {
 console.log(arguments);
});

// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');

// 添加允許跨越的頭信息
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');

// 添加支持Content-Type允許的頭信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

// 設(shè)置已攜帶憑證為true
//res.setHeader('Access-Control-Allow-Credentials', true);

res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();

運(yùn)行后,發(fā)現(xiàn)又有錯(cuò)誤提示,如下:

XMLHttpRequest cannot load http://127.0.0.1:8888/rest/user. Response to preflight request doesn't pass access control check: A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin 'http://localhost:62427' is therefore not allowed access.

分析錯(cuò)誤后發(fā)現(xiàn),原因是當(dāng)設(shè)置了已攜帶憑證參數(shù)為true時(shí),允許跨域請(qǐng)求的源不能設(shè)置為泛型的“*”,因此我們?cè)俅涡薷拇a如下:(最終代碼)

// client
$http({
 method   : 'POST',
 url   : 'http://127.0.0.1:8888/rest/user',
 withCredentials: true
 data   : {name: 'xxx',password:'***'}
 }).success(function (data) {
 console.log('login success,data is:'+data);
}).error(function (data) {
 console.log('login error');
}).then(function () {
 console.log(arguments);
});

// server
var cookie = "authId=" + authId;
res.setHeader('Content-Type', 'application/json;charset=utf-8');
res.setHeader('Set-Cookie', cookie + ';Max-Age=3600;HttpOnly=false;Path=/;');

// 添加允許跨越的頭信息
// res.setHeader('Access-Control-Allow-Origin', '*');
// 用當(dāng)前的客戶端origin來(lái)取代泛型的“*”
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:62427');

res.setHeader('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');

// 添加支持Content-Type允許的頭信息
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');

// 設(shè)置已攜帶憑證為true
res.setHeader('Access-Control-Allow-Credentials', true);

res.writeHead(200, {'Content-Type': 'text/plain'});
res.end();

此時(shí),第一次請(qǐng)求服務(wù)端時(shí),服務(wù)端返回cookie信息,以后每次客戶端請(qǐng)求服務(wù)端,客戶端的header中都會(huì)攜帶cookie信息,效果如下圖:

最后

以上就是在使用cookie記住用戶身份時(shí)遇到的一些問(wèn)題及簡(jiǎn)單解決方法,一般在angular應(yīng)用中,可能使用較多的是resoure進(jìn)行http通信,此時(shí)只要在GET/POST/PUT/DELETE等請(qǐng)求的參數(shù)中,將“withCredentials”設(shè)置為true即可。希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。

相關(guān)文章

  • 如何用DevUI搭建自己的Angular組件庫(kù)

    如何用DevUI搭建自己的Angular組件庫(kù)

    DevUI 是一款面向企業(yè)中后臺(tái)產(chǎn)品的開(kāi)源前端解決方案,它倡導(dǎo)沉浸、靈活、至簡(jiǎn)的設(shè)計(jì)價(jià)值觀,提倡設(shè)計(jì)者為真實(shí)的需求服務(wù),為多數(shù)人的設(shè)計(jì),拒絕嘩眾取寵、取悅眼球的設(shè)計(jì)。如果你正在開(kāi)發(fā) ToB 的工具類(lèi)產(chǎn)品,DevUI 將是一個(gè)很不錯(cuò)的選擇!
    2021-05-05
  • 詳解AngularJs中$resource和restfu服務(wù)端數(shù)據(jù)交互

    詳解AngularJs中$resource和restfu服務(wù)端數(shù)據(jù)交互

    之前小編和大家分享過(guò)使用$http同服務(wù)器進(jìn)行通信,但是功能上比較簡(jiǎn)單,angularjs還提供了另外一個(gè)可選的服務(wù)$resource,使用它可以非常方便的同支持restful的服務(wù)單進(jìn)行數(shù)據(jù)交互。下面來(lái)一起看看吧。
    2016-09-09
  • AngularJS實(shí)現(xiàn)單獨(dú)作用域內(nèi)的數(shù)據(jù)操作

    AngularJS實(shí)現(xiàn)單獨(dú)作用域內(nèi)的數(shù)據(jù)操作

    這篇文章給大家介紹了利用AngularJs如何實(shí)現(xiàn)ng-repeat內(nèi)各個(gè)小的子作用域單獨(dú)數(shù)據(jù)綁定。有需要的小伙伴們可以參考借鑒,下面來(lái)一起看看吧。
    2016-09-09
  • 詳解Angular2 關(guān)于*ngFor 嵌套循環(huán)

    詳解Angular2 關(guān)于*ngFor 嵌套循環(huán)

    這篇文章主要介紹了詳解Angular2 關(guān)于*ngFor 嵌套循環(huán),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-05-05
  • Angular依賴(lài)注入系統(tǒng)里Injection token PLATFORM_ID使用場(chǎng)景詳解

    Angular依賴(lài)注入系統(tǒng)里Injection token PLATFORM_ID使用場(chǎng)景詳解

    這篇文章主要為大家介紹了Angular依賴(lài)注入系統(tǒng)里Injection token PLATFORM_ID使用場(chǎng)景詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • AngularJS實(shí)踐之使用ng-repeat中$index的注意點(diǎn)

    AngularJS實(shí)踐之使用ng-repeat中$index的注意點(diǎn)

    最近通過(guò)客戶的投訴主要到在ng-repeat中使用了$index引發(fā)的一個(gè)bug,下面一起來(lái)看看這個(gè)錯(cuò)誤是如何引發(fā)的, 以及如何避免這種bug產(chǎn)生,然后說(shuō)說(shuō)我們從中得到的經(jīng)驗(yàn)和教訓(xùn)。有需要的朋友們可以參考借鑒,下面來(lái)一起看看吧。
    2016-12-12
  • angularjs下拉框空白的解決辦法

    angularjs下拉框空白的解決辦法

    這篇文章主要為大家詳細(xì)介紹了angularjs下拉框空白的解決方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-06-06
  • angularJS 發(fā)起$http.post和$http.get請(qǐng)求的實(shí)現(xiàn)方法

    angularJS 發(fā)起$http.post和$http.get請(qǐng)求的實(shí)現(xiàn)方法

    本篇文章主要介紹了angularJS 發(fā)起$http.post和$http.get請(qǐng)求的實(shí)現(xiàn)方法,分別介紹了$http.post和$http.get請(qǐng)求的方法,有興趣的可以了解一下
    2017-05-05
  • AngularJS 2.0新特性有哪些

    AngularJS 2.0新特性有哪些

    本文介紹了其在AtScript、改善依賴(lài)入駐、Annotations、路由方案等方面的改變。雖然不知道打破原有是否是件好事,不過(guò)由于不向后兼容,我們需要為遷移做好計(jì)劃
    2016-02-02
  • 詳解AngularJS 模態(tài)對(duì)話框

    詳解AngularJS 模態(tài)對(duì)話框

    在涉及GUI程序開(kāi)發(fā)的過(guò)程中,常常有模態(tài)對(duì)話框以及非模態(tài)對(duì)話框的概念。接下來(lái)通過(guò)本文給大家介紹AngularJS 模態(tài)對(duì)話框 ,感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04

最新評(píng)論

安多县| 西乡县| 象山县| 南丰县| 襄汾县| 东台市| 墨竹工卡县| 余庆县| 洛隆县| 山西省| 澳门| 河池市| 毕节市| 蓝山县| 广德县| 平阳县| 克东县| 广南县| 仁化县| 扎兰屯市| 巍山| 那坡县| 平阳县| 石屏县| 舒兰市| 大方县| 江源县| 宁远县| 青海省| 无锡市| 定安县| 霍州市| 清新县| 江城| 永定县| 宜兰市| 松江区| 江油市| 临漳县| 福清市| 祁东县|