如何阻止未经特定页面验证的用户?

时间:2014-05-13 14:52:04

标签: angularjs authentication

我想在angularjs中实现身份验证/授权系统,我找到了几个教程,其中很多使用$ routeChangeStart事件并测试特定页面,然后要求服务测试此用户是否经过身份验证通过将令牌发送到api。 这就是我所做的,但我没有得到我需要的结果。

app.js

var app = angular.module("KhbyraApp", ['ngRoute', 'ngCookies']);
app.config(function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
    .when("/Register", {
        controller: "RegisterController",
        templateUrl: "/app/views/register.html",
        authenticate : false
        })
    .when("/Login", {
        controller: "LoginController",
        templateUrl: "app/views/login.html",
        authenticate: false,
        })
    .when("/Articles", {
        controller: "ArticlesController",
        templateUrl: "app/views/article.html",
        authenticate: true
    })
    .otherwise({ redirectTo: '/Login' });

     $locationProvider.html5Mode(true);
 });

 app.run(function ($rootScope, $location, $cookieStore, AuthService) {
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if (next.authenticate) {
           if (!AuthService.isAuthenticated()) {
              $location.url("/Login");
       };
    };
});

AuthService.js

app.factory('AuthService', function ($http, $q, $window, $cookieStore) {
var factory = {};
var loginUrl = 'http://localhost:2399/Token';
var authUrl = 'http://localhost:2399/Authenticate';
var email;
var token;
factory.Authenticate = function (email, password) {
    console.log("AuthService -" + email);
    var deferred = $q.defer();
    var user = {
        email: window.btoa(email),
        password: window.btoa(password)
    };
    $http({
        method: 'POST',
        url: loginUrl,
        data: user
    }).success(function (data) {
        console.log("AuthService - " + data);
        token = data.replace('"', '').replace('"', '');
        email = user.email;
        deferred.resolve(token);
        $cookieStore.put('token', token);
        $cookieStore.put('email',user.email);
    }).error(function () {
        deferred.reject();
    });
    return deferred.promise;
};
factory.Email = email;
factory.Token = token;
factory.isAuthenticated = function () {
    var request = $http({
        method: 'GET',
        url: authUrl,
        headers: { 'Authorization': 'Token '+ $cookieStore.get('email') + ":"+ $cookieStore.get('token') }
         }).then(function () {
           return true;
        }
       ,function () {
           return false;
        });
    };
    return factory;

   });

这里的问题是在routeChangeStart中,即使AuthService.isAuthenticated()返回true,在if语句出错了,我认为它关于$ http会返回一个promise。

1 个答案:

答案 0 :(得分:0)

即使您的条件失败,加载路线也是正常的:Angular不会回滚并返回上一页。实际上在更改URL之后调用RouteChangeStart事件,当angular检测到它时..但是已经进行了重定向(实际上没有BeforeRouteChange事件)

因此,您必须根据自己的需要自行处理。例如,在这种情况下,您通常会强制重定向到登录页面。你也可以在你的页面顶部显示一个登录弹出窗口,等待登录成功重新执行先前失败的请求(现在应该可以使用,因为你现在再次登录)。这种行为很可能是http-auth-interceptor

之一

另见angular-app实现类似的东西(也基于http-auth-interceptor)