解决方法
-------------- ------------------- ------------------- | 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_USER unix系统变量有关,该变量是apache中的旧学校认证方法.
允许客户端成为django和REST API之间的身份验证链中的中间人似乎是不明智的,这似乎本质上是不安全的.相反,django可以直接调用REST API来验证用户,然后创建一个相应的django.contrib.auth.models.User对象来本地存储,这在自定义身份验证后端中执行,请参阅here.
就像是:
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
这使用requests库通过同步http请求调用REST API以记录用户,然后创建User对象的本地实例(如果尚不存在).有更复杂的远程验证协议,如果需要,http://oauth.net/2/就是一个例子.
应在settings.py文件中指定此后端
AUTHENTICATION_BACKENDS = ('my.classy.django.app.RestBackend')
然后你的django应用程序可以在它的视图中使用authenticate和login函数,使用http或json,更多信息here.
Django将request.user设置为AnonymousUser类的对象,直到用户登录,文档here.这允许您在不使用重定向的情况下区分视图中的这些用户:
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")
或者如果您希望在页面上显示“用户个人资料”框,则ala stackoverflow:
# 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并返回到客户端,而无需在客户端中重新加载页面.
通过这种方式,可以让django呈现一些模板并使用一些ajax响应来补充对REST接口的ajax请求.
这是你想要的东西吗?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。