angularjs 使用者認證實現步驟詳解

來源:互聯網
上載者:User

作為一個全棧ajax的mvvm架構,angularjs可謂如火如荼,可真正做到全棧ajax,首要面對的問題就是使用者身分識別驗證。

本文的身分識別驗證不採用cookie,而採用基於http Authorize 要求標頭的方式驗證使用者,此方式能做到永遠只有一個使用者同時線上(服務端同一時間只會接受一個合法的token請求,其他的請求返回401)

這裡我採用service儲存使用者資訊,service如下

  .factory('Authorize', function() {   return {    uid: '',    token: '',    logout: function() {     this.uid = '';     this.token = '';     localStorage.removeItem('authorize.uid');     localStorage.removeItem('authorize.token');    }   }  })

由於service是單例的。儲存在service很合適,再看登入檢測。

驗證流程

app運行時主動讀取localStorage中的authorize.uid和authorize.token欄位,將這兩個欄位發送至後端介面驗證,如果驗證成功返回使用者資訊,驗證失敗返回http 401錯誤(未授權)。

如果localStorage沒有上述兩個欄位,則檢測url中是否有,如果有則寫入本地localStorage之後發送至後端驗證,如果沒有,跳轉至後端伺服器的oauth介面進行授權拿之後,將openid和token寫入queryString並回調到app頁面,代碼如下:

     Authorize.uid = $location.search().uid || localStorage.getItem('authorize.uid');    Authorize.token = $location.search().token || localStorage.getItem('authorize.token');    if (!Authorize.uid || !Authorize.token) {     if (!Platform.isWechat) {      Authorize.uid = 1001;      Authorize.token = '2ddha3nry8';     }     else {      location.href = CONFIG.api + '/auth/oauth?callback=' + encodeURIComponent($location.protocol() + "://" + $location.host() + ":" + $location.port() + "/#" + $location.path());      return;     }    }    //寫入本地    localStorage.setItem('authorize.uid', Authorize.uid);    localStorage.setItem('authorize.token', Authorize.token);    //讀取使用者資料    var user = User.get({uid: Authorize.uid}, function() {     $rootScope.user = user;    });


讀取使用者資料這邊,採用的$resource服務封裝,這裡就不說了。

請求過程中的授權處理

接下來是比較重要的一點,如何在登陸後在每次要求標頭中注入Authorize資訊,方法是採用攔截器。

有一個問題,如果由於重新整理過快,檢測使用者回調還沒執行完,這時候訪問所有介面都是401,這裡就需要在$httpProvider上注入攔截器進行請求恢複了。代碼如下:

.factory('AuthInjector', function($q, Authorize, $injector, CONFIG) {   return {    request: function(config) {     if (Authorize.token) {      config.headers.Authorization = 'Bearer ' + Authorize.token;     }     return config;    },    response: function(response) {     var defer = $q.defer();     defer.resolve(response);     return defer.promise;    },    requestError: function(error) {    },    responseError: function(error) {     //如果401且本地存在uid,則重新整理accessToken     if (error.status == 401) {      //重新整理請求      var $http = $injector.get("$http");      $http({       method: 'GET',       url: CONFIG.api + '/auth/token',       params: {        uid: Authorize.uid       }      }).success(function(data) {       Authorize.token = data.token;       //寫入本地       localStorage.setItem('authorize.token', data.token);       return $http(error.config);      });     }     else if (error.status == 422) {      var resp;      angular.forEach(error.data, function(item) {       if (resp == undefined) {        resp = item;       }      });      return $q.reject(resp);     }     return $q.reject({      message: '請求失敗'     });    }   }  })

原理就是所有的http請求一旦返回401就進行重新登入請求,最後一句

return $http(error.config);

大體就是這麼多,總結一下就是

app.run中檢測登入

Authorize服務儲存使用者資訊

httpProvider中注入攔截器實現Authorize頭的自動添加和401結果的請求恢複

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.