mik*_*eck 5 django ajax rest django-authentication
在我的应用程序中,我需要通过我的REST API对用户进行身份验证.所以我有一个带有用户/通过字段的表单,在提交之后,我想直接进入"下一页".显然我需要通过AJAX提交表单,因为我不想被重定向到API页面.但是RemoteUserMiddleware,如果请求将由javascript处理,那么如何知道我的用户应该进行身份验证?
根据我对系统架构的理解,您目前看起来如下所示:
-------------- ------------------- -------------------
| client web | ----------> | REST API | ----> | db / persistent |
| browser | <---------- | pylons / nodejs | <---- | storage |
-------------- ------------------- -------------------
^ | ^ |
| | | |
| | | v
| | ----------------- -------------------
| ------------------> | django | ------> | db / persistent |
--------------------- | | <------ | storage |
----------------- -------------------
Run Code Online (Sandbox Code Playgroud)
您的问题涉及在REST API Web应用程序中执行身份验证时如何在django应用程序上登录和注销用户.
我不确定这RemoteUserMiddleware是你在寻找什么,它是为了在同一服务器上使用wsgi运行django时允许Apache webserver层进行身份验证.该名称与REMOTE_USERunix系统变量有关,该变量是apache中的旧学校认证方法.
允许客户端成为django和REST API之间的身份验证链中的中间人似乎是不明智的,这似乎本质上是不安全的.相反,django可以直接调用REST API来验证用户,然后创建一个相应的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
Run Code Online (Sandbox Code Playgroud)
这使用请求库通过同步http请求调用REST API以记录用户,然后创建User对象的本地实例(如果尚不存在).有更复杂的远程验证协议,如果需要,http://oauth.net/2/就是一个例子.
应在settings.py文件中指定此后端
AUTHENTICATION_BACKENDS = ('my.classy.django.app.RestBackend')
Run Code Online (Sandbox Code Playgroud)
然后你的django应用程序可以在它的视图中使用authenticate和login函数,使用http或json,更多信息在这里.
Django将设置request.user为类的对象,AnonymousUser直到用户登录,此处为docs .这使您可以在不使用重定向的情况下区分视图中的这些用户:
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")
Run Code Online (Sandbox Code Playgroud)
或者如果您希望在页面上显示"用户个人资料"框,则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")
Run Code Online (Sandbox Code Playgroud)
相反,如果您使用模板而不是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 %}
Run Code Online (Sandbox Code Playgroud)
这依赖于视图基于模板的用户对象,并且需要javascript挂钩验证后端.
它也可以用于使用render_to_string()模板呈现上下文,并将其返回到ajax请求而不是json.因此,允许在服务器上呈现html并返回到客户端,而无需在客户端中重新加载页面.
通过这种方式,可以让django呈现一些模板并使用一些ajax响应来补充对REST接口的ajax请求.
这是你想要的东西吗?
| 归档时间: |
|
| 查看次数: |
1493 次 |
| 最近记录: |