使用angularjs管理用户身份验证

时间:2013-08-15 17:26:06

标签: javascript angularjs angularjs-directive

我想知道是否有这样的方法

(这是一个非常简单的例子)

可能是管理

的起点

angularjs +用户身份验证

<!DOCTYPE html>
<html>
    <head>
        <title>My auth test</title>
    </head>
    <body>
    <div data-ng-app="myApp">
         <div data-ng-view></div>
    </div>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script>
        var app = angular.module('myApp', []);
        app.factory('Devs', function() {
            var data = [{name:'Joe',auth:false},{name:'Whisher',auth:true}];
            return data;
        });
        app.factory('Projects', function() {
            var data = [{name:'Php'},{name:'Javascript'}];
            return data;
        });
        app.config(function($routeProvider) {
            $routeProvider.
                when('/', {
                    controller: 'OneCtrl',
                    resolve: {
                        projects: function(Projects) {
                            return Projects;
                        }
                    },
                    templateUrl:'./view.html'
                }).
                when('/one', {
                    controller: 'OneCtrl',
                    resolve: {
                        projects: function(Projects) {
                            return Projects;
                        }
                    },
                    templateUrl:'./view.html'
                }).
                when('/two', {
                    controller: 'TwoCtrl',
                    resolve: {
                        projects: function(Projects) {
                            return Projects;
                        }
                    },
                    templateUrl:'./view.html'
                })
                .otherwise({redirectTo:'/'});

        });
        app.controller('OneCtrl',function($scope,Devs, projects) {
            $scope.project = projects[0];
            $scope.dev = Devs[0];
        });
        app.controller('TwoCtrl',function($scope,Devs, projects) {
            $scope.project = projects[1];
            $scope.dev = Devs[1];
        });
        app.directive('checkAuth',function($location){
            return {
                link:function(scope){
                    scope.$on('$routeChangeSuccess', function(next, current) { 
                        if(!scope.dev.auth){    
                            $location.path('/');
                        }
                    });
                }
            }
        });
    </script>
    </body>
    </html>
视图中的

<div check-auth>
<p>{{project.name}}</p>
 <div><a ng-href="./#/one">one</a></div>
 <div><a ng-href="./#/two">two</a></div>
 <div>

您只能在视图中使用该指令 要求认证。

你怎么看? 我也很满意一些链接:)

2 个答案:

答案 0 :(得分:1)

我目前正在学习角度JS。我有一天把它煮熟了:

app.factory("user", function($http, $q) {

  var user = {};

  // query logged in status on initial page load
  $http.get("/loggedin").success(function() {
    user.isLogged = true;
  }).error(function() {
    user.isLogged = false;
  });

  user.login = function(username, password) {
    var defer = $q.defer();
    if(user.isLogged) {
        defer.resolve("Already logged in");
        return defer.promise;
    }
    $http.post("/login", {username: username, password: password})
      .success(function() {
        user.isLogged = true;
        defer.resolve("User login success");
      })
      .error(function() {
        defer.reject("User login failed");
      })
    return defer.promise;
  }

  user.logout = function() {
    var defer = $q.defer();
    $http.post("/logout", {})
      .success(function() {
        // sucessfully logged out
        user.isLogged = false;
        defer.resolve();
      }).error(function() {
        // unable to logout for some reason
        defer.reject();
      });
    return defer.promise;
  }

  return user;
});

这就是Node JS中的服务器端:

module.exports = function(app) {

    // GET users
    app.get('/users', function(req, res, next) {
        async.parallel([
            function(next) {
                User.count(next);
            },
            function(next) {
                // get all users (within specified query parameters)
                var query = User.find({});
                restUtil.setSort(query, req);
                restUtil.setLimits(query, req);
                query.exec(next);
            }
        ], function(err, results) { // final callback
            if(err) {
                return next(err);
            }

            var count = results[0];
            var users = results[1];

            // add total number as header (for pagination, etc)
            res.set('total', count); 

            res.json(users);
        });
    });

    // POST a new user
    app.post('/users', hashPassword, function(req, res, next) {

        User.create(req.body, function(err, user) {
            if(err) {
                if(err.code===11000) {
                    res.send("Conflict", 409);
                } else {
                    next(err);
                }
            }
            res.json(user);
        });
    });

  // POST a login request
  app.post("/login", loadUserByUsername, function(req, res, next) {

    bcrypt.compare(req.body.password, req.user.passwordHash, function(err, ok) {
      if(ok) {
        req.session.user = req.user; // logged in
        res.send("Login ok", 200);
      } else {
        // incorrect password
        res.send("Incorrect password", 400);
      }
    })
  })

  // POST a logout request
  app.post("/logout", function(req, res, next) {
    req.session.destroy();
    res.send(200);
  })

  // GET logout status
  app.get("/loggedIn", function(req, res, next) {
    if(req.session.user) {
      res.send("Logged in", 200);
    } else {
      res.send("Not Logged in", 400)
    }
  })


  app.delete("/users/:_id", loadUserById, function(req, res, next) {
    User.remove({ _id: req.params._id }, function(err) {
      if(err) {
        res.send("An error occurred", 404);
      } else {
        res.send("Delete Success", 200);
      }
    });
  });
};

Haven还没有比现在更进一步,但我喜欢到目前为止的客户端代码。 Haven对用户角色等给予了很多考虑,但这应该让你开始。增加进一步的承诺来解决这个问题并不困难。 resolve: user.login会满足很多需求。

您也可以查看此Blog Post

答案 1 :(得分:1)

我为用户身份验证创建了AngularJS module,支持受保护/公共路由,在登录/注销时重新路由,用于状态检查的心跳,将会话令牌存储在cookie中,用于注册/登录/注销的指令,等。

它是为UserApp(基于云的用户管理API)构建的,但它可以轻松附加到您自己的API。如果使用UserApp,则不必为用户编写任何服务器端代码。拿course on Codecademy进行试用。

https://github.com/userapp-io/userapp-angular

以下是一些如何运作的例子:

  • 如何指定哪些路线应该是公开的,以及哪条路线是登录表单:

    $routeProvider.when('/login', {templateUrl: 'partials/login.html', public: true, login: true});
    $routeProvider.when('/signup', {templateUrl: 'partials/signup.html', public: true});
    $routeProvider.when('/home', {templateUrl: 'partials/home.html'});
    

    .otherwise()路由应设置为您希望用户在登录后重定向到的位置。例如:

    $routeProvider.otherwise({redirectTo: '/home'});

  • 包含错误处理的登录表单

    <form ua-login ua-error="error-msg">
        <input name="login" placeholder="Username"><br>
        <input name="password" placeholder="Password" type="password"><br>
        <button type="submit">Log in</button>
        <p id="error-msg"></p>
    </form>
    
  • 包含错误处理的注册表单

    <form ua-signup ua-error="error-msg">
      <input name="first_name" placeholder="Your name"><br>
      <input name="login" ua-is-email placeholder="Email"><br>
      <input name="password" placeholder="Password" type="password"><br>
      <button type="submit">Create account</button>
      <p id="error-msg"></p>
    </form>
    
  • 退出链接:

    <a href="#" ua-logout>Log Out</a>

    (结束会话并重定向到登录路线)

  • 访问用户属性:

    使用user服务访问用户属性,例如:user.current.email

    或在模板中:<span>{{ user.email }}</span>

  • 隐藏仅在登录时可见的元素:

    <div ng-show="user.authorized">Welcome {{ user.first_name }}!</div>

  • 根据权限显示元素:

    <div ua-has-permission="admin">You are an admin</div>

要对后端服务进行身份验证,只需使用user.token()获取会话令牌并使用AJAX请求发送它。在后端,使用UserApp API(如果您使用UserApp)检查令牌是否有效。

希望这能回答你的问题。如果您需要任何帮助,请告诉我们。)