如何在Angular JS应用程序中处理身份验证

时间:2013-08-17 11:32:45

标签: session authentication angularjs cookies

我正在我的angular js应用程序中实现一个auth系统。

我正在计划如下:

  1. 获取用户信息(姓名并从登录表单传递)
  2. 检查用户是否存在
  3. 如果存在服务器使用会话cookie响应,前端将重定向到某个页面。
  4. 然后用户将执行一些将生成API请求的任务
  5. API请求应包含在第3步发送的Cookie信息
  6. 服务器检查cookie是否已生成,如果找到cookie,则使用API​​请求结果进行响应。在我的服务中,我正在做类似
  7. 的事情
        MyApp.service('myAuth', function($http, $q) {
            this.authHeader = null;
            this.checkAuth = function(){
            //do api call and if success sets this.authHeader = response
            }
            this.isAuthenticaed = function(){
                this.authHeader ? return this.authHeder  : return false;
           }
    

    提交登录表单后,我将调用checkAuth并从我的服务器返回我的会话cookie,如何在执行下一个REST调用时添加cookie信息,以及用户在登录后在整个应用程序中导航我想要检查每次isAuthenticaed是真还是假,在Angularjs导航到另一个页面时它是否会在第一次调用后设置为true后重置?我的方法是1-6好还是你有什么具体建议吗? 顺便说一下,我检查了之前的条目,但那些不是我想知道的。

4 个答案:

答案 0 :(得分:34)

我不确定你的后端,但这就是我要做的事情

  • 创建一个单独的登录页面(专用网址不是角度子视图或 模态对话框)。
  • 如果用户未经过身份验证,则会重定向到此登录名 页。这是由服务器重定向完成的。此页面可能使用也可能不使用 角度框架,因为它只涉及发送用户\密码 服务器
  • 从登录页面发出POST(不是AJAX请求),并在服务器上验证。
  • 在服务器上设置auth cookie。 (不同的框架以不同的方式执行.ASP.Net设置表单身份验证cookie。)
  • 用户通过身份验证后,会将用户重定向到实际的角度应用并加载其所有组件。

这将保存在Angular中管理客户端身份验证所需的任何代码。如果用户登陆此页面,他将通过身份验证并拥有cookie。

此外,默认浏览器行为是发送与每个请求相关联的域的所有Cookie,因此您不必担心角度是否正在发送某些Cookie。

答案 1 :(得分:7)

我使用http-auth-interceptor。 http://ngmodules.org/modules/http-auth-interceptor

在我的后端(asp.net mvc)中,如果用户未经过身份验证,我会构建一个简单的身份验证服务并返回http错误401。 然后我使用SPA站点中的登录视图处理错误。

答案 2 :(得分:4)

之前答案提出的想法是有效的,但我认为它们过度杀伤。你不需要任何复杂的东西。

  

如何在进行下一次REST调用时添加cookie信息

默认情况下在withCredentials内打开$httpProvider,如下所示:

app.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.withCredentials = true;
}]);

然后从CORS相关标头中删除通配符(如果有的话),并在服务器端设置allow-credentials。就我而言,使用Python + Flask + Flask-Restful,它非常简单,看起来像这样:

import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app)
api.decorators = [cors.crossdomain(origin='http://localhost:8100', credentials=True)]

现在,浏览器将自动且透明地设置和返回cookie。有关详细信息,请参阅这些主题:

  

当用户在登录后浏览整个应用程序时,我确实想每次检查isAuthenticaed是或否

如上所述,如果auth会话到期或被删除,让服务器返回401,并在Angular中使用$httpInterceptor来捕获它:

app.config(function($httpProvider) {
    var interceptor =
        function($q, $rootScope) {
            return {
                'response': function(response) {
                    return response;
                 },
                'responseError': function(rejection) {
                    if (rejection.status==401) {
                        // Modify this part to suit your needs.
                        // In my case I broadcast a message which is
                        // picked up elsewhere to show the login screen.
                        if (!rejection.config.url.endsWith('/login'))
                        {
                            $rootScope.$broadcast('auth:loginRequired');
                        }
                    }

                    return $q.reject(rejection)
                 }
            }
        };

    $httpProvider.interceptors.push(interceptor);
});

答案 3 :(得分:1)

(披露:我是UserApp的开发者之一)

您可以将第三方服务UserAppAngularJS module一起使用。

查看getting started guide,或选择course on Codecademy。以下是一些如何运作的例子:

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

    <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>
    

    使用user服务访问用户信息:user.current.email

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

  • 包含错误处理的注册表单

    <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>
    

    ua-is-email表示用户名与电子邮件相同。

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

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

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

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

  • 退出链接:

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

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

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

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

如果您需要任何帮助,请告诉我:)