亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

詳解Angular開發中的登陸與身份驗證

2019-11-20 09:24:21
字體:
來源:轉載
供稿:網友

前言

由于 Angular 是單頁應用,會在一開始,就把大部分的資源加載到瀏覽器中,所以就更需要注意驗證的時機,并保證只有通過了驗證的用戶才能看到對應的界面。

本篇文章中的身份驗證,指的是如何確定用戶是否已經登陸,并確保在每次與服務器的通信中,都能夠滿足服務器的驗證需求。注意,并不包括對具體是否具有某一個權限的判斷。

對于登陸,主要是接受用戶的用戶名密碼輸入,提交到服務器進行驗證,處理驗證響應,在瀏覽器端構建身份驗證數據

實現身份驗證的兩種方式

目前,實現身份驗證的方法,主要有兩個大類:

Cookies

傳統的瀏覽器網頁,都是使用 Cookies 來驗證身份,實際上,瀏覽器端的應用層里,基本不用去管身份驗證的事情,Cookies 的設置,由服務器端完成,在提交請求的時候,由瀏覽器自動附加對應的 Cookies 信息,所以在 JavaScript 代碼中,不需要為此編寫專門的代碼。但每次請求的時候,都會帶上全部的 Cookies 數據,

隨著 CDN 的應用,移動端的逐漸興起, Cookies 越來越不能滿足復雜的、多域名下的身份驗證需求。

密鑰

實際上基于密鑰的身份驗證并不是最近才興起,它一直存在,甚至比 Cookies 歷史更長。當瀏覽器在請求服務器的時候,將密鑰以特定的方式附加在請求中,比如放在請求的頭部( headers )。為此,需要編寫專門的客戶端代碼來管理。

最近出現的基于 JSON 的 Web 密鑰(JSON Web Token)標準,便是典型的使用密鑰來實現的身份驗證。

在 Web 應用中,如果是構造 API ,則應優先考試使用密鑰方式。

處理登陸

登陸是身份驗證第一步,通過登陸,才能夠組織起來對應的身份驗證數據。

需要使用單獨的登陸頁嗎?

登陸頁的處理,有兩種方式:

單獨的登陸頁,在登陸完成后,跳轉到單頁應用之中,這樣做可以對單頁應用的資源進行訪問控制,防止非登陸用戶訪問,適合后臺或者管理工具的應用場景。但實際上降低了單頁應用的用戶體驗
在單頁應用之內執行登陸,這樣更符合單頁應用的設計理念,比較適合大眾產品的場景,因為惡意的人總是能夠拿到你單頁應用的前端代碼

單獨的登陸頁

一般情況下,使用單獨的登陸頁的目的在于保護登陸后跳轉的頁面不被匿名用戶訪問。因此,在登陸頁里,構造一個表單,直接采用傳統的表彰提交方式(非 Ajax),后端驗證用戶名密碼成功后,輸出登陸后單面應用頁面的 HTML 。

在這種情況下,可以直接將身份驗證信息放在輸出的 HTML 里,比如,可以使用 Jade 構造一個這樣的頁面:

<!-- dashboard.jade -->doctype htmlhtml head  link(rel="stylesheet", href="/assets/app.e1c2c6ea9350869264da10de799dced1.css") body  script.   window.token = !{JSON.stringify(token)};  div.md-padding(ui-view)  script(src="/assets/app.84b1e53df1b4b23171da.js")


后端在用戶名密碼驗證成功之后,可以采用如下的方式來渲染輸出 HTML :

return res.render('dashboard', { token: token});

Angular 應用一啟動,便可以進行需要使用身份驗證的通信。而且還保證了只有登陸成功的用戶才可以進入這個頁面。

單頁應用內登陸的組織

對于多視圖的 Angular 應用,一般會采用路由,在頁面之內,一般有固定的側邊欄菜單,或者頂部導航菜單,正文區域由路由模塊來控制。

下面的示例代碼,使用的是 Angular Material 來組織頁面,路由模塊使用的是 ui-router 。在應用打開的時候,有專門的加載動畫,加載完成之后,顯示的頁面,使用 AppController 這個控制器,對于沒有登陸的用戶,會顯示登陸表單,登陸完成之后,頁面分為三大部分,一是頂部面包屑導航,二是側邊欄菜單,另外就是路由控制的正文部分

代碼如下:

<body ng-app="app" layout="row"> <div id="loading">  <!--頁面加載的提示--> </div> <div flex layout="row" ng-cloak ng-controller="AppController" ng-init="load()">  <div ng-if="!isUserAuth", ng-controller="LoginController">   <!--登陸表單-->  </div>  <div ng-if="isUserAuth" flex layout="row">   <md-sidenav flex="15" md-is-locked-open="true" class="stop-text-select bbmd-sidebar md-whiteframe-4dp">    <!--側邊欄菜單-->   </md-sidenav>   <md-content flex layout="column" role="main">    <md-toolbar class="stop-text-select md-whiteframe-glow-z1">     <!--頂部菜單-->    </md-toolbar>    <md-content>     <!--路由-->     <div ui-view class="md-padding"></div>    </md-content>   </md-content>  </div> </div></body>

對于 Loading 動畫,是在 AppController 之外的,可以在 AppController 的代碼中,對其進行隱藏。這樣達到了所有 CSS / JavaScript 加載完成之后 Loading 就消失的目的。

AppController 中有一個變量 isUserAuth ,初始化的時候是 false ,當本地存儲的會話信息驗證有效,或者登陸完成之后,這個值便會置為 ture ,由于 ng-if 的控制,便可以實現隱藏登陸表單、顯示應用內容的目的。要注意,這里只有使用 ng-if 而不是 ng-show/ng-hide ,前者才會真正的刪除和增加 DOM 元素,而后者只是修改某個 DOM 元素的 CSS 屬性,這點很重要,只有這樣,才能夠保證登陸完成之后,再加載單頁應用中的內容,防止還沒有登陸,當前路由中的控制器代碼就直接執行了。

為什么客戶端也要加密密碼

一個比較理想的基于用戶名和密碼的登陸流程是這樣的:

    1.瀏覽器端獲取用戶輸入的密碼,使用 MD5 一類的哈希算法,生成固定長度的新密碼,如 md5(username + md5(md5(password))) ,再將密碼哈希值和用戶名提交給后端

    2.后端根據用戶名獲取對應的鹽,使用用戶名和密碼哈希值,算出一個密文,根據用戶名和密文去數據庫查詢

    3.如果查詢成功,則生成密鑰,返回給瀏覽器,并執行第 4 步

    4.后端生成新的鹽,根據新的鹽和瀏覽器提交的密碼哈希值,生成新的密文。在數據庫中更新鹽和密文

可能有 80% 的人無法理解為什么要把一個登陸做得這么復雜。這可能要寫一篇專門的文章才解釋得清楚。在這里先解釋一下為什么瀏覽器端要對密碼做哈希,原因如下:

    1.從源頭上保護用戶的密碼,保證只有做按鍵記錄才可以拿到用戶的原始密碼
    2.就算網絡被竊聽,又沒有使用 https ,那么被偷走的密碼,也只是哈希之后的,最多影響用戶在這個服務器里的數據,而不影響使用相同密碼的其它網站
    3.就算是服務器的所有者,都無法獲取用戶的原始密碼
這種做法,使得用戶的最大風險,也只是當前這個應用中的數據被竊取。不會擴大損失范圍,絕不會出現 CSDN 之流的問題。

登陸成功的通知

對于有些應用,并不是所有的頁面都需要用戶登陸的,可能是進行某些操作的時候,才需要登陸。在這種情況下,登陸完成之后,必須要通知整個應用。這可以使用廣播這個功能。

簡易代碼如下:

angular .module('app') .controller('LoginController', ['$rootScope', LoginController]);function LoginController($rootScope) { // 登陸成功之后調用的函數 function afterLoginSuccess() {  $rootScope.$broadcast('user.login.success', {   // 需要傳輸的數據  }); }}

在其它的控制器中,便可以監聽這個廣播,并執行登陸成功之后需要進行的操作,如獲取列表或者詳情:

$scope.$on('user.login.success', function(handle, data){ // 處理});

身份驗證信息

登陸成功之后,服務器返回了密鑰,之后的 API 請求都需要帶上密鑰,而且請求返回的響應,還需要檢查是否是關于身份信息失效的錯誤。這一系列的工作比較繁瑣,應該是自動完成才行。

保存

密鑰的保存,大概有如下幾個辦法:

    1.Cookies:前面已經提到了,這個并不推薦使用。同時,它還有最大 4k 的限制

    2.sessionStorage:tab 頁內有效,一旦關閉,或者打開了新的 tab 頁,sessionStorage 是不能共享的

    3.localStorage:較為理想的存儲方式,除非清理瀏覽器數據,否則 localStorage 存儲的數據會一直存在

    4.Angular 單例 Service:存儲在應用之內得話,刷新后數據會丟失,當然也不能 tab 頁之間共享
比較好的辦法是,身份驗證信息存儲在 localStorage 里,但在應用啟動時,初始化到 Angular 的單例 Service 中。

在請求中加入身份驗證信息

身份驗證信息的目的,是為了向服務器表明身份,獲取數據。所以,在請求中需要附加身份驗證信息。

一般的應用中,身份驗證信息都是放在請求的 headers 頭部中。如果在每次請求的時候,一一設置 headers ,那就太費時費力了。Angular 中的 $httpProvider 提供了一個攔截器 interceptors ,通過它可以實現對每一個請求和響應的統一處理。

添加攔截器的方式如下:

angular .module('app') .config(['$httpProvider', function($httpProvider){  $httpProvider.interceptors.push(HttpInterceptor); }]);

HttpInterceptor 的定義方式如下:

angular .module('app') .factory('HttpInterceptor', ['$q', HttpInterceptor]);function HttpInterceptor($q) { return {  // 請求發出之前,可以用于添加各種身份驗證信息  request: function(config){   if(localStorage.token) {    config.headers.token = localStorage.token;   }   return config;  },  // 請求發出時出錯  requestError: function(err){   return $q.reject(err);  },  // 成功返回了響應  response: function(res){   return res;  },  // 返回的響應出錯,包括后端返回響應時,設置了非 200 的 http 狀態碼  responseError: function(err){   return $q.reject(err);  } };}

攔截器提供了對發出請求到返回響應的全生命周期處理,一般可以用來做下面幾個事情:

    1.統一在發出的請求中添加數據,如添加身份驗證信息

    2.統一處理錯誤,包括請求發出時出的錯(如瀏覽器端的網絡不通),還有響應時返回的錯誤

    3.統一處理響應,比如緩存一些數據等

    4.顯示請求進度條

在上面的示例代碼中,當 localStorage 中包括 token 這個值時,就在每一個請求的頭部,添加一個 token 值。

失效及處理

一般的,后端應該在 token 驗證失敗時,將響應的 http 狀態碼設置為 401 ,這樣,在攔截器的 responseError 中便可以統一處理:

responseError: function(err){ if(-1 === err.status) {  // 遠程服務器無響應 } else if(401 === err.status) {  // 401 錯誤一般是用于身份驗證失敗,具體要看后端對身份驗證失敗時拋出的錯誤 } else if(404 === err.status) {  // 服務器返回了 404 } return $q.reject(err);}

總結

其實,只要服務器返回的狀態碼不是 200 ,都會調用 responseError ,可以在這里,統一處理并顯示錯誤。

以上內容是關于Angular開發應用中的登陸與身份驗證的相關知識,希望對大家學習Angular有所幫助。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美国产日本在线| 亚洲黄色有码视频| 在线不卡国产精品| 亚洲成人在线视频播放| 91成人天堂久久成人| 亚洲精品一区二区在线| 91国语精品自产拍在线观看性色| 国产精品一区二区久久久久| 亚洲娇小xxxx欧美娇小| 久久久国产一区二区三区| 国产精品一二区| 国产视频久久久久久久| 亚洲天堂av图片| 亚洲美女av网站| 亚洲精品日韩在线| 久久免费国产精品1| 国产网站欧美日韩免费精品在线观看| 狠狠色狠狠色综合日日小说| 久久久久久久一区二区| 亚洲福利视频免费观看| 日韩美女中文字幕| 97av在线播放| 国产aⅴ夜夜欢一区二区三区| 日韩在线视频网| 国产精品99久久久久久久久| 另类天堂视频在线观看| 日韩欧美国产激情| 欧美一区二区三区四区在线| 国产精品久久久久久久一区探花| 一区二区在线视频| 国产成人精品久久亚洲高清不卡| 国产做受高潮69| 亚洲一区亚洲二区亚洲三区| 国产亚洲一级高清| 国产成人精品亚洲精品| 欧美在线观看日本一区| 性欧美xxxx| 欧美大片第1页| 亚洲男人的天堂在线| 日韩欧美在线视频| 欧美激情a在线| 久久国产精品首页| 亚洲综合视频1区| 欧美成人免费va影院高清| 欧美亚洲国产精品| 伊人一区二区三区久久精品| 欧美激情亚洲精品| 亚洲最新中文字幕| 亚洲性xxxx| 精品少妇v888av| 久久在线免费视频| 深夜福利一区二区| 欧美一级高清免费播放| 亚洲精品视频中文字幕| 成人福利视频在线观看| 国产v综合ⅴ日韩v欧美大片| 国产a∨精品一区二区三区不卡| 国产精品一区二区av影院萌芽| 日韩在线视频播放| 国产亚洲精品高潮| 日韩久久免费电影| 久久av在线播放| 国产一区二区三区三区在线观看| 欧美另类69精品久久久久9999| 国产精品一区二区三区久久| 国产精品久久久久不卡| 欧美国产日韩在线| 成人写真视频福利网| 亚洲第一中文字幕在线观看| 久久亚洲综合国产精品99麻豆精品福利| 日韩电影在线观看永久视频免费网站| 日本高清不卡在线| 欧美日韩午夜激情| 2019中文字幕全在线观看| 久久夜精品va视频免费观看| 亚洲一品av免费观看| 欧美大奶子在线| 91免费精品国偷自产在线| 日本欧美爱爱爱| 欧美www视频在线观看| 视频在线一区二区| 91av视频在线观看| 日韩电影免费观看在线| 亚洲成人精品久久久| 亚洲天堂精品在线| 最近中文字幕mv在线一区二区三区四区| 日本精品久久久| 亚洲第一区在线| 亚洲欧美一区二区三区久久| 欧美成人中文字幕在线| 欧美大片欧美激情性色a∨久久| 日韩在线视频导航| 久久这里有精品| 中文字幕亚洲第一| 日韩电影免费观看在线观看| 97视频在线观看成人| 国产精品久久久久久搜索| 97精品一区二区视频在线观看| 欧美日韩综合视频网址| 九九九热精品免费视频观看网站| 亚洲国产成人91精品| 日韩欧美一区二区三区久久| 日韩av在线看| 成人精品一区二区三区电影免费| 国产精品久久久久久一区二区| 久久视频在线免费观看| 国产成人精品日本亚洲专区61| 亚洲免费小视频| 97视频在线观看成人| 日韩av一区在线观看| 精品久久久久久中文字幕一区奶水| 国外视频精品毛片| 亚洲欧美视频在线| 亚洲乱码一区二区| 欧美激情精品久久久久久大尺度| 久久亚洲国产精品| 亚洲乱码国产乱码精品精天堂| 欧美午夜女人视频在线| 91久久精品一区| 亚洲第一中文字幕| 亚洲天堂免费视频| 一区二区三区久久精品| 日韩久久免费电影| 91精品国产自产91精品| 伦理中文字幕亚洲| 国产日韩欧美日韩| 国产91精品不卡视频| 97av在线视频| 久久精品视频va| 亚洲女人天堂色在线7777| 全色精品综合影院| 中文字幕日韩视频| 亚洲aⅴ日韩av电影在线观看| 欧美疯狂做受xxxx高潮| 亚洲综合日韩在线| 亚洲国模精品私拍| 热re91久久精品国99热蜜臀| 国产视频999| 亚洲人午夜精品免费| 亚洲美女中文字幕| 国产一区深夜福利| 久久综合久久八八| 久久综合免费视频| 国产精品热视频| 国产精品视频网址| 亚洲国产精品va在线看黑人| 91久久在线播放| 亚洲www视频| 亚洲缚视频在线观看| 国产亚洲视频在线| 欧美在线免费视频| 911国产网站尤物在线观看| 国产精品香蕉在线观看| 清纯唯美亚洲综合| 亚洲女人天堂av| 午夜精品一区二区三区av| 美女黄色丝袜一区| 欧美成人在线免费视频| 91香蕉嫩草影院入口| 性色av一区二区三区红粉影视| 精品久久香蕉国产线看观看亚洲| 国产精品在线看| 国产午夜精品久久久| 日韩精品在线观看网站|