Django的远程身份验证不重定向 [英] Django Remote Authentication without redirecting
问题描述
在我的应用程序需要通过我的REST API来验证用户身份。所以,我有一个用户名/密码字段的形式,并提出申请后,我想直接进入下一个页面。所以,显然我需要通过AJAX提交我的形式,因为我不希望被重定向到API页面。但如何那么 RemoteUserMiddleware
就会知道,如果该请求将被JavaScript处理我的用户进行身份验证?
In my application I need to authenticate users via my REST API. So I have a form with user/pass fields, and after submitting it, I'd like to proceed directly to the 'next' page. So apparently I need to submit my form via AJAX, as I don't want to be redirected to the API page. But how then the RemoteUserMiddleware
will know that my user should be authenticated if the request will be processed by javascript ?
推荐答案
要我的系统架构,你必须了解目前看起来是这样的:
To my understanding of the system architecture you have currently looks something like the following:
-------------- ------------------- -------------------
| client web | ----------> | REST API | ----> | db / persistent |
| browser | <---------- | pylons / nodejs | <---- | storage |
-------------- ------------------- -------------------
^ | ^ |
| | | |
| | | v
| | ----------------- -------------------
| ------------------> | django | ------> | db / persistent |
--------------------- | | <------ | storage |
----------------- -------------------
您的问题涉及到了如何在认证开展的REST API的webapp的Django应用程序和退出用户登录。
Your question relates to how to log in and out users on the django app when the authentication is carried out in the REST API webapp.
我不知道该 RemoteUserMiddleware
是你在找什么,它被设计为允许认证通过Apache网络服务器层时,Django是使用WSGI在运行同一台服务器。该名称涉及在Apache的一个老同学的身份验证方法 REMOTE_USER
UNIX系统变量。
I'm not sure that the RemoteUserMiddleware
is what you are looking for, it is designed to allow authentication by an Apache webserver layer when django is run using wsgi on that same server. The name relates to the REMOTE_USER
unix system variable which is an old school authentication method in apache.
这似乎不明智,让客户在Django和你的REST API的认证链条的中介,这似乎是天生不安全的。相反,Django的可以直接调用REST API来验证用户身份,然后创建一个对应的 django.contrib.auth.models.User
对象存储在本地,这是进行自定义认证后端,看到<一href="https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#writing-an-authentication-backend"相对=nofollow>这里。
It seems unwise to allow the client to be an intermediary in the authentication chain between django and your REST API, this would seem to be inherently insecure. Instead, django can call the REST API directly to authenticate users and then create a corresponding django.contrib.auth.models.User
object to store locally this is carried out in a custom authentication backend, see 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
本使用请求库调用REST API与同步HTTP请求来记录用户然后创建用户对象的本地实例,如果不存在。有进行远程验证更复杂的协议,如果需要的话, http://oauth.net/2/ 是一个例如,
This uses the requests library to call the REST API with a synchronous http request to log the user in and then creates a local instance of the User object, if one doesn't already exist. There are more complicated protocols for remote authentication, if required, http://oauth.net/2/ is an example.
这个后端应在 settings.py
文件中指定
This backend should be specified in the settings.py
file
AUTHENTICATION_BACKENDS = ('my.classy.django.app.RestBackend')
那么你的Django应用程序可以使用验证
和登录
的功能在里面的观点,无论是使用HTTP或JSON,更多信息这里。
Then your django app can use the authenticate
and login
functions in it's views, either using http or json, more info here.
Django会设置 request.user
是类的一个对象 AnonymousUser
,直到用户登录,文档这里。这使您可以向这些用户在你的看法区分,而无需使用重定向:
Django will set the request.user
to be an object of class AnonymousUser
until the user is logged in, docs here. This allows you to differentiate between these users in your views without using redirects:
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计算器:
or if you wanted a 'user profile' box to appear on the page, 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来渲染页面,然后这个逻辑可以被传递给模板,与地区出现,当用户登录时,无需使用重定向:
If, instead, you are using templates and not ajax to render your page then this logic could be passed to the template, with areas appearing when a user logs in, without having to use redirects:
{% 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挂钩的认证后端。
This relies on the user object being based into the template by the view, and would require the javascript to hook up the authenticate the backend.
也可以使用 render_to_string()
来渲染模板的背景下,并返回这一个Ajax请求,而不是JSON。由此允许的html在服务器上渲染,并返回到客户端,而无需重新加载该页面在客户端
It is also possible to use render_to_string()
to render a context with a template, and return this to an ajax request instead of json. Thus allowing html to be rendered on the server and returned to the client without having to reload the page in the client.
在这种方式,可以让Django的渲染一些模板,并使用一些Ajax响应,以补充Ajax请求到您的REST接口。
In this manner it is possible to get django to render some templates and use some ajax responses to complement ajax requests to your REST interface.
这是不是像你在找什么?
Is this something like what you are looking for?
这篇关于Django的远程身份验证不重定向的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!