使用OAuth打造webapi認證服務供自己的客戶端使用(二)


在上一篇”使用OAuth打造webapi認證服務供自己的客戶端使用“的文章中我們實現了一個采用了OAuth流程3-密碼模式(resource owner password credentials)的WebApi服務端。今天我們來實現一個js+html版本的客戶端。

一、angular客戶端

angular版本的客戶端代碼來自於http://bitoftech.net/2014/06/01/token-based-authentication-asp-net-web-api-2-owin-asp-net-identity/,接下來我們做個簡單的梳理,方便大家在項目中使用。

1、新建一個angular module,我們使用ngRoute來實現一個單頁面程序,LocalStorageModule用來在本地存放token信息,angular-loading-bar是一個頁面加載用的進度條。

var app = angular.module('AngularAuthApp', ['ngRoute', 'LocalStorageModule', 'angular-loading-bar']);

2、新建一個constant,angular中的constant可以注入到任意service和factory中,是存儲全局變量的好幫手。

app.constant('ngAuthSettings', {
    apiServiceBaseUri: 'http://localhost:56646/',
    clientId: 'ngAuthApp'
});

地址:http://localhost:56646/就是我們自己的webApi地址。

3、authService中定義了登錄和登出邏輯,登錄邏輯就是我們使用OAuth2.0中的流程3獲取token的過程,一旦獲得到token也就意味着我們登錄成功了。

var _login = function (loginData) {

        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;

        var deferred = $q.defer();

        $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {

            if (loginData.useRefreshTokens) {
                localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true });
            }
            else {
                localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: "", useRefreshTokens: false });
            }
            _authentication.isAuth = true;
            _authentication.userName = loginData.userName;
            _authentication.useRefreshTokens = loginData.useRefreshTokens;

            deferred.resolve(response);

        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });


        return deferred.promise;

    };

我們按照OAuth2.0中的流程3來Post數據,拿到token信息后保存在localStorageService。

3、啟動AngularClient.Web項目嘗試一下登錄

由於同源策略的原因,我們需要在WebApi服務端啟用cors,打開Startup類配置cors:

4、一旦登錄成功意味着我們拿到了token,所以可以憑token訪問受限的資源,例如http://localhost:56646/api/orders。只需要在每個請求頭中加入Authorization:Bearer {{token}}即可。

我們可以使用angular的攔截功能,只需要在$http服務中攔截每個請求,在請求頭中加入token即可。

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('authInterceptorService');
});

angular中的provider是可以配置的,正如上面的代碼我們添加了一個authInterceptorService攔截服務。

攔截邏輯也很簡單:如果在localStorageService中讀到token,就添加一個header。

var _request = function (config) {

        config.headers = config.headers || {};
       
        var authData = localStorageService.get('authorizationData');
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }

        return config;
    }

5、再次登錄,當登錄成功后成功調用到了http://localhost:56646/api/orders服務

二、JQuery客戶端

JQuery客戶端的實現思路也差不多,首先發一個post請求獲取token:

var apiServiceBaseUri = 'http://localhost:56646/';
        $('#login').click(function () {
            var data = {
                'grant_type': 'password',
                'username': $('#userName').val(),
                'password': $('#password').val()
            };
            $.ajax({
                url: apiServiceBaseUri + 'token',
                type: "POST",
                data: data,
                dataType: 'json',
                success: function (data) {
                    $.cookie("token", data.access_token);
                    getOrders();
                },
                error: function (xmlHttpRequest) {
                    $("#message").html(xmlHttpRequest.responseJSON.error_description);
                    $("#message").show();
                }
            });

token一旦獲取成功就保存在cookie中。接下來拿token去訪問受限的服務:

var getOrders = function () {
            $.ajax({
                beforeSend: function (xhr) {
                    xhr.setRequestHeader('Authorization', 'Bearer ' + $.cookie("token"));
                },
                url: apiServiceBaseUri + 'api/orders',
                type: "GET",
                dataType: 'json',
                success: function (data) {
                    showOrderTable(data);
                }
            });
        }

通過xhr.setRequestHeader('Authorization', 'Bearer ' + $.cookie("token")); 的方式將token添加到請求頭,相對angular的攔截方案,此方案就顯得比較繁瑣了,每個http請求都得有添加此行代碼。

所有代碼同步更新在 https://git.oschina.net/richieyangs/OAuthPractice.git


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM