国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
如何在 Angular 中使用 withCredentials 屬性?
Angular 中 HttpInterceptor 的用途是什么?
如何創(chuàng)建自定義 HttpInterceptor 來(lái)處理 withCredentials?
為什么在使用 withCredentials 時(shí)會(huì)收到 CORS 錯(cuò)誤?
如何使用 XMLHttpRequest withCredentials 屬性?
首頁(yè) web前端 js教程 在角度應(yīng)用中實(shí)施身份驗(yàn)證

在角度應(yīng)用中實(shí)施身份驗(yàn)證

Feb 21, 2025 am 08:40 AM

Implementing Authentication in Angular Applications

關(guān)鍵要點(diǎn)

  • 在單頁(yè)應(yīng)用程序 (SPA) 中實(shí)現(xiàn)身份驗(yàn)證涉及服務(wù)器公開(kāi)身份驗(yàn)證端點(diǎn),該端點(diǎn)驗(yàn)證用戶憑據(jù)并返回訪問(wèn)令牌。此令牌隨后用于對(duì)服務(wù)器進(jìn)行的所有安全 API 請(qǐng)求。
  • 在 Angular 中,訪問(wèn)令牌可以存儲(chǔ)在服務(wù)或值中,因?yàn)樗鼈兪强蛻舳松系膯卫龑?duì)象。但是,為了防止用戶刷新頁(yè)面時(shí)令牌丟失,建議使用瀏覽器持久性機(jī)制(例如 sessionStorage)來(lái)存儲(chǔ)令牌。
  • 為了防止?jié)撛诘臄?shù)據(jù)盜竊,應(yīng)在服務(wù)器端和客戶端維護(hù)和驗(yàn)證用戶的狀態(tài)。當(dāng)用戶注銷時(shí),應(yīng)調(diào)用相應(yīng)的 API(請(qǐng)求標(biāo)頭中包含訪問(wèn)令牌),并且還應(yīng)清除 sessionStorage 中的數(shù)據(jù)。

身份驗(yàn)證和授權(quán)是幾乎所有嚴(yán)肅應(yīng)用程序的重要組成部分。單頁(yè)應(yīng)用程序 (SPA) 也不例外。應(yīng)用程序可能不會(huì)將其所有數(shù)據(jù)和功能都公開(kāi)給任何用戶。用戶可能必須進(jìn)行身份驗(yàn)證才能查看應(yīng)用程序的某些部分,或在應(yīng)用程序上執(zhí)行某些操作。為了識(shí)別應(yīng)用程序中的用戶,我們需要讓用戶登錄。

在傳統(tǒng)的服務(wù)器驅(qū)動(dòng)應(yīng)用程序和單頁(yè)應(yīng)用程序中,用戶管理的實(shí)現(xiàn)方式有所不同。SPA 與其服務(wù)器組件交互的唯一方式是通過(guò) AJAX。即使對(duì)于登錄和注銷也是如此。

負(fù)責(zé)識(shí)別用戶的服務(wù)器必須公開(kāi)身份驗(yàn)證端點(diǎn)。SPA 將把用戶輸入的憑據(jù)發(fā)送到此端點(diǎn)進(jìn)行驗(yàn)證。在典型的基于令牌的身份驗(yàn)證系統(tǒng)中,服務(wù)在驗(yàn)證憑據(jù)后可能會(huì)返回訪問(wèn)令牌或包含已登錄用戶的名稱和角色的對(duì)象。客戶端必須在對(duì)服務(wù)器進(jìn)行的所有安全 API 請(qǐng)求中使用此訪問(wèn)令牌。

由于訪問(wèn)令牌將被多次使用,因此最好將其存儲(chǔ)在客戶端。在 Angular 中,我們可以將值存儲(chǔ)在服務(wù)或值中,因?yàn)樗鼈兪强蛻舳松系膯卫龑?duì)象。但是,如果用戶刷新頁(yè)面,服務(wù)或值中的值將丟失。在這種情況下,最好使用瀏覽器提供的持久性機(jī)制之一來(lái)存儲(chǔ)令牌;最好是 sessionStorage,因?yàn)樗跒g覽器關(guān)閉后會(huì)被清除。

實(shí)現(xiàn)登錄

現(xiàn)在讓我們來(lái)看一些代碼。假設(shè)我們已經(jīng)實(shí)現(xiàn)了所有服務(wù)器端邏輯,并且服務(wù)在 /api/login 處公開(kāi)了一個(gè) REST 端點(diǎn)來(lái)檢查登錄憑據(jù)并返回訪問(wèn)令牌。讓我們編寫(xiě)一個(gè)簡(jiǎn)單的服務(wù),通過(guò)訪問(wèn)身份驗(yàn)證端點(diǎn)來(lái)執(zhí)行登錄操作。稍后我們將向此服務(wù)添加更多功能:

app.factory("authenticationSvc", function($http, $q, $window) {
  var userInfo;

  function login(userName, password) {
    var deferred = $q.defer();

    $http.post("/api/login", {
      userName: userName,
      password: password
    }).then(function(result) {
      userInfo = {
        accessToken: result.data.access_token,
        userName: result.data.userName
      };
      $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);
      deferred.resolve(userInfo);
    }, function(error) {
      deferred.reject(error);
    });

    return deferred.promise;
  }

  return {
    login: login
  };
});

在實(shí)際代碼中,您可能希望將存儲(chǔ)數(shù)據(jù)到 sessionStorage 的語(yǔ)句重構(gòu)到單獨(dú)的服務(wù)中,因?yàn)槿绻覀冞@樣做,此服務(wù)將承擔(dān)多個(gè)責(zé)任。為了使演示保持簡(jiǎn)單,我將其保留在同一個(gè)服務(wù)中。此服務(wù)可以由處理應(yīng)用程序登錄功能的控制器使用。

保護(hù)路由

我們可能在應(yīng)用程序中有一組受保護(hù)的路由。如果用戶未登錄并嘗試進(jìn)入這些路由之一,則應(yīng)將用戶定向到登錄頁(yè)面。這可以使用路由選項(xiàng)中的 resolve 塊來(lái)實(shí)現(xiàn)。以下代碼片段說(shuō)明了實(shí)現(xiàn)方法:

$routeProvider.when("/", {
  templateUrl: "templates/home.html",
  controller: "HomeController",
  resolve: {
    auth: ["$q", "authenticationSvc", function($q, authenticationSvc) {
      var userInfo = authenticationSvc.getUserInfo();

      if (userInfo) {
        return $q.when(userInfo);
      } else {
        return $q.reject({ authenticated: false });
      }
    }]
  }
});

resolve 塊可以包含多個(gè)語(yǔ)句塊,這些語(yǔ)句塊必須在完成時(shí)返回 promise 對(duì)象。只是為了澄清,上面定義的名稱 auth 不是由框架定義的;我定義了它。您可以根據(jù)用例將名稱更改為任何名稱。

有多種原因會(huì)導(dǎo)致傳遞或拒絕路由。根據(jù)場(chǎng)景,您可以在解析/拒絕 promise 時(shí)傳遞對(duì)象。我們尚未在服務(wù)中實(shí)現(xiàn) getLoggedInUser() 方法。這是一個(gè)簡(jiǎn)單的方法,它從服務(wù)返回 loggedInUser 對(duì)象。

app.factory("authenticationSvc", function() {
  var userInfo;

  function getUserInfo() {
    return userInfo;
  }
});

通過(guò)上述代碼片段中 promise 發(fā)送的對(duì)象通過(guò) $rootScope 廣播。如果路由已解析,則會(huì)廣播事件 $routeChangeSuccess。但是,如果路由失敗,則會(huì)廣播事件 $routeChangeError。我們可以監(jiān)聽(tīng) $routeChangeError 事件并將用戶重定向到登錄頁(yè)面。由于事件位于 $rootScope 級(jí)別,因此最好在運(yùn)行塊中附加事件處理程序。

app.run(["$rootScope", "$location", function($rootScope, $location) {
  $rootScope.$on("$routeChangeSuccess", function(userInfo) {
    console.log(userInfo);
  });

  $rootScope.$on("$routeChangeError", function(event, current, previous, eventObj) {
    if (eventObj.authenticated === false) {
      $location.path("/login");
    }
  });
}]);

處理頁(yè)面刷新

當(dāng)用戶點(diǎn)擊頁(yè)面的刷新按鈕時(shí),服務(wù)會(huì)丟失其狀態(tài)。我們必須從瀏覽器的 sessionStorage 獲取數(shù)據(jù)并將其分配給變量 loggedInUser。由于工廠只調(diào)用一次,因此我們可以在初始化函數(shù)中設(shè)置此變量,如下所示。

function init() {
  if ($window.sessionStorage["userInfo"]) {
    userInfo = JSON.parse($window.sessionStorage["userInfo"]);
  }
}

init();

注銷

當(dāng)用戶從應(yīng)用程序注銷時(shí),必須調(diào)用相應(yīng)的 API,并在請(qǐng)求標(biāo)頭中包含訪問(wèn)令牌。用戶注銷后,我們也應(yīng)該清除 sessionStorage 中的數(shù)據(jù)。以下示例包含必須添加到身份驗(yàn)證服務(wù)的注銷函數(shù)。

function logout() {
  var deferred = $q.defer();

  $http({
    method: "POST",
    url: logoutUrl,
    headers: {
      "access_token": userInfo.accessToken
    }
  }).then(function(result) {
    $window.sessionStorage["userInfo"] = null;
    userInfo = null;
    deferred.resolve(result);
  }, function(error) {
    deferred.reject(error);
  });

  return deferred.promise;
}

結(jié)論

在單頁(yè)應(yīng)用程序中實(shí)現(xiàn)身份驗(yàn)證的方法與傳統(tǒng) Web 應(yīng)用程序的方法大相徑庭。由于大部分工作是在客戶端進(jìn)行的,因此用戶的狀態(tài)也必須存儲(chǔ)在客戶端的某個(gè)位置。重要的是要記住,也必須在服務(wù)器端維護(hù)和驗(yàn)證狀態(tài),因?yàn)楹诳涂赡軙?huì)竊取存儲(chǔ)在客戶端系統(tǒng)上的數(shù)據(jù)。

本文中的源代碼可在 GitHub 上下載。

關(guān)于在 Angular 應(yīng)用程序中實(shí)現(xiàn)身份驗(yàn)證的常見(jiàn)問(wèn)題解答

如何在 Angular 中使用 withCredentials 屬性?

withCredentials 屬性用于在 HTTP 請(qǐng)求中包含身份驗(yàn)證 cookie。在 Angular 中,您可以在 HttpClient 模塊中使用它。發(fā)出請(qǐng)求時(shí),您可以將 withCredentials 屬性設(shè)置為 true。這是一個(gè)示例:

this.http.get(url, { withCredentials: true }).subscribe(...);

這將包含服務(wù)器之前可能已發(fā)送的任何 cookie。

Angular 中 HttpInterceptor 的用途是什么?

HttpInterceptor 是 Angular 中的一項(xiàng)功能,允許您在將 HTTP 請(qǐng)求發(fā)送到服務(wù)器之前全局?jǐn)r截和修改它們。它對(duì)于各種任務(wù)非常有用,例如向所有請(qǐng)求添加身份驗(yàn)證令牌或全局處理錯(cuò)誤。

如何創(chuàng)建自定義 HttpInterceptor 來(lái)處理 withCredentials?

要?jiǎng)?chuàng)建自定義 HttpInterceptor,您需要?jiǎng)?chuàng)建一個(gè)實(shí)現(xiàn) HttpInterceptor 接口的服務(wù)。這是一個(gè)示例:

app.factory("authenticationSvc", function($http, $q, $window) {
  var userInfo;

  function login(userName, password) {
    var deferred = $q.defer();

    $http.post("/api/login", {
      userName: userName,
      password: password
    }).then(function(result) {
      userInfo = {
        accessToken: result.data.access_token,
        userName: result.data.userName
      };
      $window.sessionStorage["userInfo"] = JSON.stringify(userInfo);
      deferred.resolve(userInfo);
    }, function(error) {
      deferred.reject(error);
    });

    return deferred.promise;
  }

  return {
    login: login
  };
});

此攔截器將克隆每個(gè)請(qǐng)求并將 withCredentials 屬性設(shè)置為 true。

為什么在使用 withCredentials 時(shí)會(huì)收到 CORS 錯(cuò)誤?

CORS(跨源資源共享)是一項(xiàng)安全功能,它限制了跨域共享資源的方式。如果您收到 CORS 錯(cuò)誤,則表示服務(wù)器未配置為接受來(lái)自您域的請(qǐng)求。要解決此問(wèn)題,您需要將服務(wù)器配置為在“Access-Control-Allow-Origin”標(biāo)頭中包含您的域,并將“Access-Control-Allow-Credentials”設(shè)置為 true。

如何使用 XMLHttpRequest withCredentials 屬性?

XMLHttpRequest withCredentials 屬性的工作方式與 Angular HttpClient withCredentials 屬性類似。它用于在請(qǐng)求中包含 cookie。這是一個(gè)示例:

$routeProvider.when("/", {
  templateUrl: "templates/home.html",
  controller: "HomeController",
  resolve: {
    auth: ["$q", "authenticationSvc", function($q, authenticationSvc) {
      var userInfo = authenticationSvc.getUserInfo();

      if (userInfo) {
        return $q.when(userInfo);
      } else {
        return $q.reject({ authenticated: false });
      }
    }]
  }
});

這將發(fā)送包含 cookie 的 GET 請(qǐng)求到指定的 URL。

其余的常見(jiàn)問(wèn)題解答與HttpClientModule 的使用有關(guān),與文章的核心主題(Angular 中的身份驗(yàn)證實(shí)現(xiàn))關(guān)系不大,因此在此處省略。 這些問(wèn)題可以很容易地通過(guò)搜索引擎找到答案。

以上是在角度應(yīng)用中實(shí)施身份驗(yàn)證的詳細(xì)內(nèi)容。更多信息請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本站聲明
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣服圖片

Undresser.AI Undress

Undresser.AI Undress

人工智能驅(qū)動(dòng)的應(yīng)用程序,用于創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用于從照片中去除衣服的在線人工智能工具。

Clothoff.io

Clothoff.io

AI脫衣機(jī)

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智能換臉工具輕松在任何視頻中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的代碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

功能強(qiáng)大的PHP集成開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)代碼編輯軟件(SublimeText3)

熱門(mén)話題

如何在JS中與日期和時(shí)間合作? 如何在JS中與日期和時(shí)間合作? Jul 01, 2025 am 01:27 AM

JavaScript中的日期和時(shí)間處理需注意以下幾點(diǎn):1.創(chuàng)建Date對(duì)象有多種方式,推薦使用ISO格式字符串以保證兼容性;2.獲取和設(shè)置時(shí)間信息可用get和set方法,注意月份從0開(kāi)始;3.手動(dòng)格式化日期需拼接字符串,也可使用第三方庫(kù);4.處理時(shí)區(qū)問(wèn)題建議使用支持時(shí)區(qū)的庫(kù),如Luxon。掌握這些要點(diǎn)能有效避免常見(jiàn)錯(cuò)誤。

為什么要將標(biāo)簽放在的底部? 為什么要將標(biāo)簽放在的底部? Jul 02, 2025 am 01:22 AM

PlacingtagsatthebottomofablogpostorwebpageservespracticalpurposesforSEO,userexperience,anddesign.1.IthelpswithSEObyallowingsearchenginestoaccesskeyword-relevanttagswithoutclutteringthemaincontent.2.Itimprovesuserexperiencebykeepingthefocusonthearticl

什么是在DOM中冒泡和捕獲的事件? 什么是在DOM中冒泡和捕獲的事件? Jul 02, 2025 am 01:19 AM

事件捕獲和冒泡是DOM中事件傳播的兩個(gè)階段,捕獲是從頂層向下到目標(biāo)元素,冒泡是從目標(biāo)元素向上傳播到頂層。1.事件捕獲通過(guò)addEventListener的useCapture參數(shù)設(shè)為true實(shí)現(xiàn);2.事件冒泡是默認(rèn)行為,useCapture設(shè)為false或省略;3.可使用event.stopPropagation()阻止事件傳播;4.冒泡支持事件委托,提高動(dòng)態(tài)內(nèi)容處理效率;5.捕獲可用于提前攔截事件,如日志記錄或錯(cuò)誤處理。了解這兩個(gè)階段有助于精確控制JavaScript響應(yīng)用戶操作的時(shí)機(jī)和方式。

JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS JavaScript模塊上的確定JS綜述:ES模塊與COMPORJS Jul 02, 2025 am 01:28 AM

ES模塊和CommonJS的主要區(qū)別在于加載方式和使用場(chǎng)景。1.CommonJS是同步加載,適用于Node.js服務(wù)器端環(huán)境;2.ES模塊是異步加載,適用于瀏覽器等網(wǎng)絡(luò)環(huán)境;3.語(yǔ)法上,ES模塊使用import/export,且必須位于頂層作用域,而CommonJS使用require/module.exports,可在運(yùn)行時(shí)動(dòng)態(tài)調(diào)用;4.CommonJS廣泛用于舊版Node.js及依賴它的庫(kù)如Express,ES模塊則適用于現(xiàn)代前端框架和Node.jsv14 ;5.雖然可混合使用,但容易引發(fā)問(wèn)題

如何在node.js中提出HTTP請(qǐng)求? 如何在node.js中提出HTTP請(qǐng)求? Jul 13, 2025 am 02:18 AM

在Node.js中發(fā)起HTTP請(qǐng)求有三種常用方式:使用內(nèi)置模塊、axios和node-fetch。1.使用內(nèi)置的http/https模塊無(wú)需依賴,適合基礎(chǔ)場(chǎng)景,但需手動(dòng)處理數(shù)據(jù)拼接和錯(cuò)誤監(jiān)聽(tīng),例如用https.get()獲取數(shù)據(jù)或通過(guò).write()發(fā)送POST請(qǐng)求;2.axios是基于Promise的第三方庫(kù),語(yǔ)法簡(jiǎn)潔且功能強(qiáng)大,支持async/await、自動(dòng)JSON轉(zhuǎn)換、攔截器等,推薦用于簡(jiǎn)化異步請(qǐng)求操作;3.node-fetch提供類似瀏覽器fetch的風(fēng)格,基于Promise且語(yǔ)法簡(jiǎn)單

編寫(xiě)清潔和可維護(hù)的JavaScript代碼的最佳實(shí)踐是什么? 編寫(xiě)清潔和可維護(hù)的JavaScript代碼的最佳實(shí)踐是什么? Jun 23, 2025 am 12:35 AM

要寫(xiě)出干凈、可維護(hù)的JavaScript代碼,應(yīng)遵循以下四點(diǎn):1.使用清晰一致的命名規(guī)范,變量名用名詞如count,函數(shù)名用動(dòng)詞開(kāi)頭如fetchData(),類名用PascalCase如UserProfile;2.避免過(guò)長(zhǎng)函數(shù)和副作用,每個(gè)函數(shù)只做一件事,如將更新用戶信息拆分為formatUser、saveUser和renderUser;3.合理使用模塊化和組件化,如在React中將頁(yè)面拆分為UserProfile、UserStats等小組件;4.寫(xiě)注釋和文檔時(shí)點(diǎn)到為止,重點(diǎn)說(shuō)明關(guān)鍵邏輯、算法選

var vs Let vs const:快速JS綜述解釋器 var vs Let vs const:快速JS綜述解釋器 Jul 02, 2025 am 01:18 AM

var、let和const的區(qū)別在于作用域、提升和重復(fù)聲明。1.var是函數(shù)作用域,存在變量提升,允許重復(fù)聲明;2.let是塊級(jí)作用域,存在暫時(shí)性死區(qū),不允許重復(fù)聲明;3.const也是塊級(jí)作用域,必須立即賦值,不可重新賦值,但可修改引用類型的內(nèi)部值。優(yōu)先使用const,需改變變量時(shí)用let,避免使用var。

See all articles