问题
I have a Django web application which requires authentication across the whole site. I've accomplished that with custom middleware which basically test if request.user.is_anonymous
and, if they are, redirects them to the login page. It looks like this:
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)
Now I'm making an iOS app which, for now, will just do GET requests off the Django server. I am trying to use TastyPie to do this but I can't get the the authentication working. I am using ApiKeyAuthentication
and, I believe, have set it up properly. However, it just redirects me to the login page. I'm wondering if I need to edit this middleware to handle TastyPie requests, but I thought TastyPie could to auth for me...
I feel like my situation is very similar to this question, but I wonder if my custom middleware is getting in the way.
Here's my 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()
And a portion of my 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....
The URL I try to navigate to is:
http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345?format=json
But I'm just redirected to my login page. I've followed the tutorial to a tee, created an api key on my Admin panel, and added WSGIPassAuthorization On
to my apache config.
Any ideas?
EDIT I just removed that middleware altogether and now all I receive are 401 AUTHENTICATION errors...
EDIT 2
I should point out that if I remove the ?format=json
then I get a response of: Sorry, not implemented yet. Please append "?format=json" to your URL.
. So it's like it does authenticate, but then fails because I'm not specifying the format.
So my URL looks like this: http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345
but as soon as I add the ?format=JSON
then it goes to a 401 error.
回答1:
TastyPie requests go through the same stack of middlewares as any typical django request. So, it's definitely your middleware. You have to rethink it, or just drop to the basics and use @login_required.
The api key doesn't work after you disabled the middleware because your URL is malformed. You can't use a ? in a querystring after you used it once. Try this url:
http://192.168.1.130:8080/ios/v1/system/C0156/?username=garfonzo&api_key=12345&format=JSON
来源:https://stackoverflow.com/questions/25573037/django-tastypie-authentication-and-custom-middleware-headache