在我的应用程序中,我需要通过REST API对用户进行身份验证。因此,我有一个包含用户/密码字段的表单,提交后,我想直接进入“下一个”页面。显然,我不想通过AJAX提交表单,因为我不想重定向到API页面。但是RemoteUserMiddleware,如果请求将由javascript处理,那么如何知道我的用户应该进行身份验证?
RemoteUserMiddleware
根据我对系统体系结构的了解,您目前看起来像以下内容:
-------------- ------------------- ------------------- | client web | ----------> | REST API | ----> | db / persistent | | browser | <---------- | pylons / nodejs | <---- | storage | -------------- ------------------- ------------------- ^ | ^ | | | | | | | | v | | ----------------- ------------------- | ------------------> | django | ------> | db / persistent | --------------------- | | <------ | storage | ----------------- -------------------
您的问题与在REST API Web应用程序中执行身份验证时如何在django应用程序上登录和注销用户有关。
我不确定RemoteUserMiddleware您要寻找的是什么,它设计为允许在同一服务器上使用wsgi运行django时通过Apache Web服务器层进行身份验证。该名称与REMOTE_USERunix系统变量有关,后者是apache中的一种旧式身份验证方法。
REMOTE_USER
让客户端成为django和您的REST API之间的身份验证链的中介似乎是不明智的,这似乎是天生的不安全。相反,django可以直接调用REST API来对用户进行身份验证,然后创建一个相应的django.contrib.auth.models.User对象以将其存储在本地,这是在自定义身份验证后端中进行的,请参见此处。
django.contrib.auth.models.User
就像是:
from django.contrib.auth.models import User import requests class RestBackend(object): supports_inactive_user = False def authenticate(self, username=None, password=None): rest_response = requests.post('http://your.rest.interface/auth', data={ 'username' : username, 'password' : password }).json() if rest_response['error'] == 'None': try: user = User.objects.get(username=username) except User.DoesNotExist: user = User(username=username, password=password) user.save() return user return user def get_user(self, user_id): try: return User.objects.get(pk=user_id) except User.DoesNotExist: return None
它使用请求库通过同步的http请求来调用REST API,以登录用户,然后创建User对象的本地实例(如果尚不存在)。有很多复杂的远程身份验证协议,如果需要,http://oauth.net/2/是一个示例。
该后端应在settings.py文件中指定
settings.py
AUTHENTICATION_BACKENDS = ('my.classy.django.app.RestBackend')
那么你的Django应用程序可以使用authenticate和login功能在它的观点,无论是使用HTTP或JSON,更多信息在这里。
authenticate
login
Django会设置request.user为类的对象AnonymousUser,直到用户登录,文件在这里。这使您可以在视图中区分这些用户,而无需使用重定向:
request.user
AnonymousUser
from django.http import HttpResponse from django.utils import simplejson from myApp.models impor InfoObject def infoPage(request): # return info objects for logged in user, or all info objects otherwise if request.user.is_authenticated(): infoObjects = InfoObject.objects.filter(user=request.user).orderby("-pubdate") else: infoObjects = InfoObject.objects.orderby("-pubdate") return HttpResponse(simplejson.dumps(infoObjects), content_type = "application/json")
或者,如果您想在页面上显示“用户个人资料”框,则如下所示:
# helper function that can be called from all your views def getUserInfo(request): if request.user.is_authenticated(): return UserInfo.objects.get(user=user) else: return [] def randomPage(request): info = getUserInfo(request) .....other page logic.... return HttpResponse('['+simplejson.dumps(..pageData..)+','+simplejson.dumps(info)+']', content_type = "application/json")
相反,如果使用的是模板而不是ajax来呈现页面,则可以将此逻辑传递给模板,并在用户登录时显示区域,而不必使用重定向:
{% extends "base.html" %} {% block userInfo %} <div id="userArea"> {% if user.is_authenticated %} User: {{ user.username }}<br /> geezer score: {{ userProfile.geezerScore }}<br /> <input type="button" value="log out" /> {% else %} Username: <input type="text" id="username" /> password: <input type="password" id="password" /> <input type="button" value="log in" /> {% endif %} </div> {% endblock %}
这依赖于用户对象是基于视图的模板,并且需要javascript来连接身份验证后端。
也可以使用render_to_string()模板渲染上下文,并将其返回给ajax请求而不是json。因此,无需在客户端中重新加载页面就可以在服务器上呈现html并将其返回给客户端。
render_to_string()
通过这种方式,可以使django渲染一些模板并使用一些ajax响应来补充对REST接口的ajax请求。
这是您想要的东西吗?