【问题标题】:How do I check that user already authenticated from tastypie?如何检查该用户是否已通过来自美味派的身份验证?
【发布时间】:2011-11-13 21:00:54
【问题描述】:

当用户在 Django 中进行身份验证时,我如何从 sweetpie 中检查?

一旦用户登录,该视图会包含一些从 API 中提取数据的 JS,这些数据由美味派支持。

我的资源上设置了基本身份验证/djangoauthorisation,因此浏览器会弹出 http auth 窗口。有什么办法可以避免吗?

到目前为止,我的想法是扩展 BasicAuthentication 以便它首先检查会话数据,当它没有找到它时,它会退回到 http auth? AFAIK AJAX 调用包括会话 cookie,所以理论上这应该有效吗?有人做过类似的吗?

【问题讨论】:

    标签: ajax django tastypie


    【解决方案1】:

    到目前为止我有这个解决方案:

    class MyBasicAuthentication(BasicAuthentication):
        def __init__(self, *args, **kwargs):
            super(MyBasicAuthentication, self).__init__(*args, **kwargs)
    
        def is_authenticated(self, request, **kwargs):
            from django.contrib.sessions.models import Session
            if 'sessionid' in request.COOKIES:
                s = Session.objects.get(pk=request.COOKIES['sessionid'])
                if '_auth_user_id' in s.get_decoded():
                    u = User.objects.get(id=s.get_decoded()['_auth_user_id'])
                    request.user = u
                    return True
            return super(MyBasicAuthentication, self).is_authenticated(request, **kwargs)
    

    这似乎符合我的要求。如果用户已登录,则 session 包含_auth_user_id,如果没有,则缺少密钥。

    谁能想到这种方法可能导致的任何问题?

    【讨论】:

      【解决方案2】:

      您可能想在 sweetpie 的 GitHub 上查看这张票:

      https://github.com/toastdriven/django-tastypie/issues/197

      作者提出了一种非常简洁的方法来使用会话和 API 密钥方法对调用进行身份验证。

      sn-p 出现了:

      class ApiKeyPlusWebAuthentication(ApiKeyAuthentication):
      def is_authenticated(self, request, **kwargs):
          if request.user.is_authenticated():
              return True
      
          return super(ApiKeyPlusWebAuthentication, self).is_authenticated(request, **kwargs)
      
      def get_identifier(self, request):
          if request.user.is_authenticated():
              return request.user.username
          else:
              return super(ApiKeyPlusWebAuthentication, self).get_identifier(request)
      

      【讨论】:

        【解决方案3】:

        一旦用户通过您的 API 登录,您就有了一个 Django 用户会话。如果您想检查用户是否仍然登录(例如在页面刷新时)。你可以这样做:

        from tastypie.resources import Resource
        
        class LoggedInResource(Resource):
            class Meta:
                pass
        
            def get_list(self, request, **kwargs):
        
                from django.http import HttpResponse
        
                if request.user.is_authenticated():
                    return HttpResponse(status=200)
                else:
                    return HttpResponse(status=401)
        

        客户检查:

        $.ajax({
            type: "GET",
            url: '/api/loggedin/',
            success: function(data) {
                // logged in
            },
            error: function() {
                // not logged in
            }
        });
        

        【讨论】:

          【解决方案4】:

          芍药

          为什么不简单如下:

          class CommAuthentication(BasicAuthentication):
              def __init__(self, *args, **kwargs):
                  super(CommAuthentication, self).__init__(*args, **kwargs)
          
              def is_authenticated(self, request, **kwargs):
                  return request.user.is_authenticated()
          

          我刚开始学习美味派。上面的代码似乎对我有用。您的解决方案有什么优势吗?

          【讨论】:

          • 我认为这只有在请求已经过身份验证并且已设置会话 cookie 时才有效。如果您发送设置了 HTTP Basic Auth 标头的请求,这将失败,因为没有会话并且您没有调用超类 is_authenticated 方法,该方法应该可以处理这种情况。
          • 感谢 Pulegium。 “我认为这只有在请求已经过身份验证的情况下才有效”,难道不希望以这种方式以编程方式访问 API 吗?就身份验证而言,最佳实践是什么?目前我有一个单独的登录 api 来验证用户。只有成功通过登录api的用户才能使用其他的restful api。不确定这种做法是否可行。
          • 顺便说一句,在我的登录 api 中我启动了 session-cookie
          • 我对 RESTful API 的理解是不应该维护任何状态(或会话)。换句话说,您在请求中提供的信息应该足以处理它。这意味着,您必须在每个请求中发送登录信息(作为 HTTP 基本身份验证或 API 密钥)。
          猜你喜欢
          • 1970-01-01
          • 2022-09-29
          • 1970-01-01
          • 2017-07-15
          • 2018-12-21
          • 2020-06-24
          • 2018-12-28
          • 1970-01-01
          • 2017-07-10
          相关资源
          最近更新 更多