【问题标题】:Django, TastyPie, Authentication, and custom middleware headacheDjango、TastyPie、身份验证和自定义中间件头痛
【发布时间】:2014-10-23 17:54:57
【问题描述】:

我有一个 Django Web 应用程序,它需要对整个站点进行身份验证。我已经使用自定义中间件完成了这一点,该中间件基本上测试request.user.is_anonymous,如果是,则将它们重定向到登录页面。它看起来像这样:

from django.contrib.auth.views import login
from django.contrib.auth import authenticate
from django.http import HttpResponseRedirect, HttpResponse
from django.utils import simplejson
from django.core import serializers

class SiteLogin:
    "This middleware requires a login for every view"
    def process_request(self, request):
        if request.path != '/accounts/login/' and request.user.is_anonymous():
            if request.POST:
                return login(request)
            else:
                return HttpResponseRedirect('/accounts/login/?next=%s' % request.path)

现在我正在制作一个 iOS 应用程序,目前它只会从 Django 服务器发出 GET 请求。我正在尝试使用 TastyPie 来执行此操作,但我无法使身份验证正常工作。我正在使用ApiKeyAuthentication,并且我相信已经正确设置了它。但是,它只是将我重定向到登录页面。我想知道我是否需要编辑这个中间件来处理 TastyPie 请求,但我认为 TastyPie 可以为我进行身份验证......

我觉得我的情况与this question 非常相似,但我想知道我的自定义中间件是否妨碍了我。

这是我的api.py

from django.contrib.auth.models import User
from django.db import models
from tastypie.resources import ModelResource
from cpm.systems.models import System
from cpm.products.models import Product
from tastypie.models import create_api_key
from tastypie.authentication import ApiKeyAuthentication
from tastypie.authorization import DjangoAuthorization, Authorization

models.signals.post_save.connect(create_api_key, sender=User)



class SystemResource(ModelResource):
  class Meta:   
    queryset = System.objects.all()
    resource_name = 'system'
    authentication = ApiKeyAuthentication()
    authorization = DjangoAuthorization()


class ProductResource(ModelResource):
  class Meta:       
    queryset = Product.objects.all()
    resource_name = 'product'
    authentication = ApiKeyAuthentication()
    authorization = DjangoAuthorization()

还有我的一部分urls.py

from cpm.ios.api import SystemResource, ProductResource
from tastypie.api import Api

v1_api = Api(api_name='v1')
v1_api.register(SystemResource())
v1_api.register(ProductResource())

admin.autodiscover()

urlpatterns = patterns('',

    # iOS TastyPie related:
    (r'^ios/', include(v1_api.urls)),
    # .... more urls....

我尝试导航到的 URL 是:

http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345?format=json

但我只是被重定向到我的登录页面。我已经按照教程进行了 tee,在我的管理面板上创建了一个 api 密钥,并将WSGIPassAuthorization On 添加到我的 apache 配置中。

有什么想法吗?

编辑我刚刚完全删除了该中间件,现在我收到的只是 401 AUTHENTICATION 错误...

编辑 2 我应该指出,如果我删除?format=json,那么我会得到回复:Sorry, not implemented yet. Please append "?format=json" to your URL.。所以它就像它确实进行身份验证,但随后失败,因为我没有指定格式。

所以我的 URL 看起来像这样:http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345,但只要我添加了?format=JSON,它就会出现 401 错误。

【问题讨论】:

  • 回复:格式=JSON。当您将一对附加到查询字符串时,?仅在开始时使用。其余的对用 & 分隔。所以,你的查询字符串/网址应该看起来像 - 192.168.1.130:8080/ios/v1/system/C0156/…
  • @dekomote - 哇 - 成功了!好的,所以我更近了一步。只要我使用我的自定义中间件,我现在实际上可以正确地进行身份验证。所以这是一个很好的进展。所以这个问题的后半部分仍然存在——我的 middleware.py(显示有问题)现在妨碍了。我设置错了吗? TastyPie 不应该能够为我导航/验证,从而绕过我的中间件吗?

标签: django tastypie django-authentication


【解决方案1】:

TastyPie 请求与任何典型的 django 请求都通过相同的中间件堆栈。所以,它绝对是你的中间件。您必须重新考虑它,或者只使用基础知识并使用@login_required。

在您禁用中间件后,api 密钥不起作用,因为您的 URL 格式错误。你不能使用 ?使用一次后在查询字符串中。试试这个网址:

http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345&format=JSON

【讨论】:

  • 是的——这是我的问题,URL 格式错误。所以,我有很多观点(这是一个大型企业网站)。这是否意味着我需要用@login_required 来装饰它们all 只是为了让tastepie 能够做到这一点?
  • 嗯,你可以有很多方法:如果你使用基于类的视图,你可以添加一个 mixin 来处理它。您可以添加中间件,但请检查请求是否将发送到美味的视图...
  • 好吧,很酷,想一想。至少我知道我的问题的根本原因是什么,并且至少可以确定解决问题的好方法。谢谢你的帮助!在过去的 48 小时里,我一直在拔头发!
猜你喜欢
  • 2021-02-06
  • 2016-11-30
  • 2014-11-13
  • 2019-04-09
  • 1970-01-01
  • 2016-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多