Python Tastypie:GET的身份验证和POST的匿名验证
我使用Django/tastypi来管理我的用户集合 是否可以允许匿名用户在API中发布(在某个端点创建新用户时),并限制经过身份验证的用户仅获取自己的用户,而不获取所有用户Python Tastypie:GET的身份验证和POST的匿名验证,python,django,api,rest,tastypie,Python,Django,Api,Rest,Tastypie,我使用Django/tastypi来管理我的用户集合 是否可以允许匿名用户在API中发布(在某个端点创建新用户时),并限制经过身份验证的用户仅获取自己的用户,而不获取所有用户 谢谢你的帮助。是的,两者都可以 下面是一个简单的示例,说明如何让经过身份验证的用户只获取自己的用户JSON,而不从所有其他用户获取JSON:(假设您使用的是Django的内置用户基础架构): 下面是一个简单的示例,说明如何让匿名用户发布帖子来创建新用户(注意:严格来说,这不使用Tastype) 我发现最简单的方法是对我正在
谢谢你的帮助。是的,两者都可以 下面是一个简单的示例,说明如何让经过身份验证的用户只获取自己的用户JSON,而不从所有其他用户获取JSON:(假设您使用的是Django的内置用户基础架构): 下面是一个简单的示例,说明如何让匿名用户发布帖子来创建新用户(注意:严格来说,这不使用Tastype)
我发现最简单的方法是对我正在使用的身份验证类进行子类化。只要覆盖
is\u authenticated
方法,在方法POST时返回True
class AnonymousPostAuthentication(BasicAuthentication):
""" No auth on post / for user creation """
def is_authenticated(self, request, **kwargs):
""" If POST, don't check auth, otherwise fall back to parent """
if request.method == "POST":
return True
else:
return super(AnonymousPostAuthentication, self).is_authenticated(request, **kwargs)
我将验证放在验证
的子类中,覆盖是否有效
我和上面Sampson做的一样做GET过滤 这是解决我问题的唯一办法吗?因为,正如你说的“严格来说,这不使用Tastypie”不,这不是唯一的方法;但是,当您阅读代码时,您可以看出解决方案非常简单(大部分是输入验证)。这个想法是,你不必在所有事情上都使用Tastype。有另一种方法可以用Tastypie实现,但它更复杂。更一般地说,如果您只是使用一种技术/软件来解决问题,而没有考虑它是否最适合,或者是否有更好/更简单的方法来解决问题,那么您就有可能遇到金锤反模式:谢谢。工作得很好。我稍微修改了代码,因为我只需要为GET禁用身份验证,并为所有其他方法保留它。
# In views.py:
...
from django.http import HttpResponse
from django.contrib.auth.models import User, Group
from django.contrib.auth import authenticate
from django.http import Http404
from django.utils import timezone
from models import *
from api import *
from django.utils import simplejson
...
# REST endpoint for user registration
# Enforces server-side mediation (input validation)
# On failure, raises Http404
# On success, redirects to registration success page
def register_user(request):
if request.method != 'POST':
raise Http404('Only POSTs are allowed')
# acquire params
username = request.POST['username']
password = request.POST['password']
repeatpw = request.POST['repeatpw']
first_name = request.POST['first_name']
last_name = request.POST['last_name']
# Server-side mediation to check for invalid input
if username == '' or username is None:
raise Http404('Server-side mediation: Invalid Username')
if len(username) > 30:
raise Http404('Server-side mediation: username must be 30 characters or fewer')
if len(first_name) > 30:
raise Http404('Server-side mediation: first name must be 30 characters or fewer')
if len(last_name) > 30:
raise Http404('Server-side mediation: last name msut be 30 characters or fewer')
if len(password) < 4:
raise Http404('Server-side mediation: Password too short')
if password != repeatpw:
raise Http404('Server-side mediation: Password Mismatch')
# This try-except block checks existence of username conflict
try:
test_user_exists = User.objects.get(username__exact=username)
if test_user_exists != None:
raise Http404('Server-side mediation: Username exists')
except User.DoesNotExist:
pass
# Input passes all tests, proceed with user creation
user = User.objects.create_user(username, 'default@nomail.com', password)
group = Group.objects.get(name='Standard')
user.first_name = first_name
user.last_name = last_name
user.groups.add(group)
user.is_staff = False
user.save()
# Build confirmation JSON
confirmation = {
'action': 'register_user',
'username': username,
'success': 'yes',
}
json_return = simplejson.dumps(confirmation)
# return JSON of the success confirmation
return HttpResponse(json_return, mimetype='application/json')
#!/bin/bash
echo "Usage: ./register_user username password repeatpw first_name last_name"
curl -v -d "username=$1&password=$2&repeatpw=$3&first_name=$4&last_name=$5" http://127.0.0.1:8000/register_user/ > result
class AnonymousPostAuthentication(BasicAuthentication):
""" No auth on post / for user creation """
def is_authenticated(self, request, **kwargs):
""" If POST, don't check auth, otherwise fall back to parent """
if request.method == "POST":
return True
else:
return super(AnonymousPostAuthentication, self).is_authenticated(request, **kwargs)