加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ajax – 没有重定向的Django远程身份验证

发布时间:2020-12-16 02:53:45 所属栏目:百科 来源:网络整理
导读:在我的应用程序中,我需要通过我的REST API对用户进行身份验证.所以我有一个带有用户/通过字段的表单,在提交之后,我想直接进入“下一页”.显然我需要通过 AJAX提交表单,因为我不想被重定向到API页面.但是,如果请求将由 javascript处理,RemoteUserMiddleware如
在我的应用程序中,我需要通过我的REST API对用户进行身份验证.所以我有一个带有用户/通过字段的表单,在提交之后,我想直接进入“下一页”.显然我需要通过 AJAX提交表单,因为我不想被重定向到API页面.但是,如果请求将由 javascript处理,RemoteUserMiddleware如何知道我的用户应该进行身份验证?

解决方法

根据我对系统架构的理解,您目前看起来如下所示:

--------------             -------------------       -------------------
       | 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请求.

这是你想要的东西吗?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读