【问题标题】:django and angular.js with authentication带有身份验证的 django 和 angular.js
【发布时间】:2015-03-04 05:58:17
【问题描述】:

我有一个已经用 Django 编写的网络应用程序,并且运行良好。我想为角度添加一些视图,因为计划是朝着那个方向移动。我面临的一个问题是我的一些控制器需要登录,对于 django,我们通常使用 @login_required 装饰器,一切都很好。

但是使用 angular.js 调用控制器(对于 api 的),重定向不会发生。我假设我必须以某种方式检查我的 django 用户是否直接从角度侧进行了身份验证。关于如何在角度上确认这一点有什么解释吗?我一直在努力解决这个问题并阅读了以下内容:

https://docs.angularjs.org/api/ng/service/$http

https://medium.com/@vince_prignano/angular-js-with-django-bde834dbd61e

$routeProvider not triggered after login redirect

http://www.django-rest-framework.org/api-guide/authentication/

基本上,我想通过 Angular 确认我的用户已登录,如果没有,则将他们重定向到登录页面。

编辑

我正在实现一个请求拦截器,如下所示:

Interceptor not working

但是,在 django @login_required 中,它返回了重定向页面的 html。有没有办法获取 URL 并在那里转发用户?

【问题讨论】:

    标签: django angularjs


    【解决方案1】:

    在你的 $routeProvider 中添加解析为:

        $routeProvider 
          .when('/', { 
             templateUrl: '/views/main.html' }) 
          .when('/admin', {
             templateUrl: 'views/admin.html', 
             controller: 'AdminCtrl', 
             resolve: { loggedin: checkLoggedin } }) 
          .when('/login', { 
             templateUrl: 'views/login.html', 
             controller: 'LoginCtrl' }) 
          .otherwise({ redirectTo: '/' }); -
    

    查看更多信息:https://vickev.com/#!/article/authentication-in-single-page-applications-node-js-passportjs-angularjs

    【讨论】:

      【解决方案2】:

      如上一个答案所述,如果您的 Django 后端可以在需要登录时发出 401 响应,那将是最好的。现在听起来它正在发送一个 302,如果您正在发出 XHR 请求,您仍然可以在浏览器中观察到它。如您所见,在 Angular 中使用 $http 拦截器是查找 401 并将用户发送到登录页面的常用方法。

      我采用了不同的方法:通过一个名为 $user.get() 的方法实现一个稍微抽象的服务 - 它向已知端点(在我的例子中为 /api/users/current)发出请求并拒绝返回的承诺如果它看到 401。在您的情况下,您可以实现一个拒绝处理程序,该处理程序使用 window.location.href 将用户发送到您的专用登录页面

      免责声明:我在 Stormpath 工作,我们花了很多时间思考这个问题 :) 在我上面的 cmets 中,我指的是我们的 Stormpath Angular SDK - 你可以看看这个库,看看我是怎么做的已经解决了这个问题。

      【讨论】:

        【解决方案3】:

        在定义我的应用时,我正在这样做:

        $httpProvider.interceptors.push('errorInterceptor');

        代码如下:

        app.factory('errorInterceptor', ['$q', '$rootScope', '$location',
            function ($q, $rootScope, $location) {
                return {
                    request: function (config) {
                        return config || $q.when(config);
                    },
                    requestError: function(request){
                        return $q.reject(request);
                    },
                    response: function (response) {
                        return response || $q.when(response);
                    },
                    responseError: function (response) {
                        if (response && response.status == 302 && response.data.url) {
                            window.location = response.data.url;
                            return;
                        }
                        return $q.reject(response);
                    }
                };
        }]);
        

        基本上,我们不能使用login_required。我们必须创建一个新的装饰器并提供一个带有 url 的 302 状态。

        【讨论】:

          【解决方案4】:

          如果您通过 AJAX 将 API 调用返回到服务器,很可能您不希望将响应重定向到登录页面。

          我有相同的用例,并制作了自己的装饰器,以在用户未登录时返回 403。如果您愿意,也可以使用 401 代替(我把它注释掉了)。

          我使用 403 因为401 seems to imply WWW authentication

          from django.http import HttpResponse, HttpResponseForbidden
          
          
          def logged_in_or_deny(func):
              def check_request(request, *args, **kwargs):
                  if (request.user.is_authenticated()):
                      return func(request, *args, **kwargs)
                  else:
                      return HttpResponseForbidden('You must be logged in')       # 403 Response
                      #return HttpResponse('You must be logged in', status=401)    # 401 Response
              return check_request
          

          然后你会像这样保护你的视图:

          @logged_in_or_deny
          def your_view(request):
              # ... your code ...
              return HttpResponse('Your normal response :)')
          

          从 Angular 看来,您似乎已经知道如何使用拦截器来检查响应代码并相应地重定向用户。如果您使用 403 或 401,您应该检查响应正文,以防您将来响应类似错误。

          虽然您已经拥有的内容可以使用,但 302 响应可以用于其他原因。最好有明确的 4xx 响应而不是 3xx 重定向响应,因为它会立即很明显是客户端错误(缺少身份验证)。

          【讨论】:

            【解决方案5】:

            您可以使用 Http-Auth-Interceptor。假设一个视图需要登录并且用户在没有登录的情况下向视图发出请求,然后@login_required 装饰器返回响应代码为 401 的响应。在 auth 拦截器中,如果状态代码为 401,则拦截状态代码,然后将用户重定向到登录页面。

            示例网站:http://witoldsz.github.io/angular-http-auth/

            【讨论】:

              猜你喜欢
              • 2014-05-05
              • 2013-10-25
              • 1970-01-01
              • 2018-03-25
              • 2014-07-05
              • 2013-01-24
              • 2014-08-27
              • 2012-01-01
              • 2018-02-26
              相关资源
              最近更新 更多