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

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

问题描述

在我的应用程序中,我需要通过我的REST API来验证用户。所以我有一个用户/通行证的表单,提交后,我想直接进入下一个页面。显然,我需要通过AJAX提交表单,因为我不想被重定向到API页面。但是,如果这个请求将被javascript处理,那么如何使用 RemoteUserMiddleware 会知道我的用户应该被认证

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 是您正在寻找的,它旨在允许通过当使用同一服务器上的wsgi运行django时,Apache Web服务器层。该名称与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 对象来存储本地,这是在自定义中执行的认证后端,请参阅此处

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

这使用请求库使用同步http请求调用REST API来记录用户,然后创建User对象的本地实例(如果尚不存在)。如果需要,还有更复杂的远程身份验证协议, 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 文件中指定

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 直到用户登录,docs here 。这可以让您在视图中区分这些用户,而不使用重定向:

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 stackoverflow:

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响应来补充你的REST接口的ajax请求。

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天全站免登陆