Django的远程身份验证不重定向 [英] Django Remote Authentication without redirecting

查看:197
本文介绍了Django的远程身份验证不重定向的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序需要通过我的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆