2

このブログのコードを使用して、Angular アプリの認証モジュールを作成しています。

ログインフォーム、送信ボタン、および制限されたルートを照会する「プロファイル」ボタンを含むテストページがあります。

<div class="container-fluid" ng-controller="AuthCtrl as auth">
    <input type="text" ng-model="auth.user.username">
    <input type="text" ng-model="auth.user.password">
    <button ng-click="auth.login(auth.user)">LOGIN</button>
    <button ng-click="auth.profile()">PROFILE</button>
</div>

ログイン後に照会している制限付きルートは次のように定義されています。

const authenticate = expressJwt({
  secret: SECRET
});
app.get('/me', authenticate, function(req, res) {
  res.status(200).json(req.user);
});

ログインは正常に機能します。sessionStorage に入れたトークンを受け取ります。プロフィール ボタン (/me へのリクエスト) をクリックすると、不正なエラーが発生します。

ページを更新してプロファイルをもう一度クリックすると、期待どおりの動作が得られます。(/me はエラーなしでユーザー データを返します)

その後手動でトークンを削除しても、ページを更新するまで /me にアクセスできます。

これは私のサービスです:

function loginService($http) {
    this.login = function(user) {
        return $http.post('/auth', user).then(
            function(response) {
                return response.data;
            },
            function(response) {
                return response;
            });
    };
    this.profile = function() {
        return $http.get('/me').then(
            function(response) {
                return response.data;
            },
            function(response) {
                return response;
            });
    };
}

angular
    .module('app')
    .service('loginService', loginService);

これは、httpProvider を使用したコントローラーです。

function AuthCtrl($window, $http, loginService) {
    this.user = {username: "", password: ""};
    this.login = function(user) {
        loginService.login(user).then(function(data) {
            $window.sessionStorage.token = data.token;
        });
    };
    this.profile = function() {
        loginService.profile().then(function(data) {
            console.log(data);
        });
    };
}

function config($httpProvider, $windowProvider) {
    var window = $windowProvider.$get();
    if(window.sessionStorage.token) {
        var token =  window.sessionStorage.token;
        $httpProvider.defaults.headers.common.Authorization = 'Bearer ' + token;
    }
};

angular
    .module('app')
    .config(config)
    .controller('AuthCtrl', AuthCtrl);

問題は、トークンを sessionStorage に保存すること、または http プロバイダーから発生する可能性がありますか?

最終的には安全な Cookie メソッドを実装しますが、先に進む前にこれを解決したいと思います。

4

1 に答える 1

1

$httpProvider私は最終的にそれがコードのために来ていることを理解しました。

function config($httpProvider, $windowProvider) {
    var window = $windowProvider.$get();
    if(window.sessionStorage.token) {
        var token =  window.sessionStorage.token;
        $httpProvider.defaults.headers.common.Authorization = 'Bearer ' + token;
    }
};

プロバイダー オプションは、アプリの読み込み中に 1 回だけ設定されました。ページをリロードすると、構成コードが再実行if(window.sessionStorage.token)され、期待どおりの状態になります。

この構成を動的にするには、次のようにインターセプター(ファクトリー)を作成する必要がありました。

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

function authInterceptor($rootScope, $q, $window) {
    return {
        request: function (config) {
            config.headers = config.headers || {};
            if ($window.sessionStorage.token) {
                config.headers.Authorization = 'Bearer ' + $window.sessionStorage.token;
            }
            return config;
        },
        responseError: function (rejection) {
            if (rejection.status === 401) {
                console.log("not authorised");
            }
            return $q.reject(rejection);
        }
    };
};

angular
    .module('app')
    .config(config)
    .controller('AuthCtrl', AuthCtrl)
    .factory('authInterceptor', authInterceptor);
于 2016-07-07T08:35:15.453 に答える