18

我正在我的 Angular js 应用程序中实现一个身份验证系统。

我的计划如下:

  1. 获取用户信息(登录表单中的名称和传递)
  2. 检查用户是否存在
  3. 如果存在服务器以会话 cookie 响应,前端将重定向到某个页面。
  4. 然后用户将执行一些将生成 API 请求的任务
  5. API 请求应包含在步骤 3 中发送的 cookie 信息
  6. 服务器检查是否生成了 cookie,如果找到了 cookie,则使用 API 请求结果进行响应。在我的服务中,我正在做类似的事情
    MyApp.service('myAuth', function($http, $q) {
        this.authHeader = null;
        this.checkAuth = 函数(){
        //做api调用,如果成功设置this.authHeader = response
        }
        this.isAuthenticaed = function(){
            这个.authHeader ?返回 this.authHeder :返回 false;
       }

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

4

4 回答 4

35

我不确定你的后端,但我会这样做

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

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

此外,默认浏览器行为是在每个请求中发送与域关联的所有 cookie,因此您不必担心 angular 是否发送了一些 cookie。

于 2013-08-17T13:25:15.697 回答
7

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

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

于 2013-08-17T22:06:24.567 回答
4

前面的答案提出的想法会奏效,但我认为它们太过分了。你不需要这么复杂的东西。

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

withCredentials里面默认开启$httpProvider如下:

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

然后从与 CORS 相关的标头中删除通配符(如果有的话),并在服务器端设置允许凭据。就我而言,使用 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 true 或 false

如上所述,如果身份验证会话过期或被删除,则让服务器返回 401,并$httpInterceptor在 Angular 中使用如下方式捕获:

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);
});
于 2015-08-07T18:08:05.430 回答
1

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

为此,您可以使用第三方服务UserApp以及AngularJS 模块

查看入门指南,或参加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检查令牌是否有效。

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

于 2013-12-15T23:16:30.940 回答