我已经在Django项目中设置了Tastypie,并且API正确地提供了资源。我现在正尝试允许移动用户(应用程序)通过所述API进行注册,登录和注销。
class BaseResource(ModelResource):
class Meta:
allowed_methods = [ 'get' ]
authentication = BasicAuthentication()
class UserResource(BaseResource):
class Meta:
queryset = User.objects.all()
resource_name = 'users'
...
class ProfileResource(BaseResource):
class Meta:
queryset = Profile.objects.all()
resource_name = 'profiles'
...
所以这是我的第一个目的。关于登录,我不认为BasicAuthentication
被用于移动设备的请求。根据我的阅读,似乎有几种方法可以做我想要的事情:
第一个链接(请参阅the answer)让我烦恼的是移动应用程序必须发送包含原始密码的JSON:
{ 'username' : 'me', 'password' : 'l33t' }
是否有人/东西可以获取此JSON,从而可以访问密码?使用ApiKeyAuthentication
不是更好吗?
我越来越明白我读到的内容越来越少。如果该帐户是从网络平台(django-userena
)创建的,则我无法使用ApiKeyAuthentication
,因为应创建密钥when a new User
is saved。
我可以找到几种方法来做我想做的事情,而且我找不到正确的一个......我确实已经意识到这个问题已被多次询问和回答,但我和#39;正在寻找关于以最佳方式实现这一点的方向。
答案 0 :(得分:0)
我最终做了以下事情:
# ──────────────────────────────────────────────────────────────────────────────
class BaseResource(ModelResource):
# ──────────────────────────────────────
def prepend_urls(self):
try:
additional_urls = self._meta.additional_urls
except AttributeError:
additional_urls = []
return [url(r'^'+u[0]+'$', self.wrap_view(u[1]), name=u[2]) for u in additional_urls]
# ──────────────────────────────────────
def update_in_place(self, request, original_bundle, new_data):
try:
allowed_fields = self._meta.allowed_fields
except AttributeError:
allowed_fields = None
if allowed_fields and set(new_data.keys()) - set(allowed_fields):
raise BadRequest('Only alterable field(s): {}'.format(', '.join(allowed_fields)))
return super(ProfileResource, self).update_in_place(request, original_bundle, new_data)
# ──────────────────────────────────────
class Meta:
abstract = True
allowed_methods = ['get',]
authentication = ApiKeyAuthentication()
authorization = DjangoAuthorization()
max_limit = 1000
# ──────────────────────────────────────────────────────────────────────────────
class UserResource(BaseResource):
...
# ──────────────────────────────────────
def signup(self, request, **kwargs):
...
# ──────────────────────────────────────
def signin(self, request, **kwargs):
self.method_check(request, allowed=['post'])
data = self.deserialize(
request,
request.body,
format=request.META.get('CONTENT_TYPE', 'application/json')
)
username = data.get('username', '')
password = data.get('password', '')
user = authenticate(username=username, password=password)
if user:
if user.is_active:
# login(request, user)
try:
key = ApiKey.objects.get(user=user)
if not key.key:
key.save()
except ApiKey.DoesNotExist:
key = ApiKey.objects.create(user=user)
return self.create_response(request, {
'success': True,
'data': key.key,
})
else:
return self.create_response(request, {
'success': False,
'message': 'User is not active',
}, HttpForbidden)
else:
return self.create_response(request, {
'success': False,
'message': 'Wrong password',
}, HttpUnauthorized)
# ──────────────────────────────────────
class Meta(BaseResource.Meta):
allowed_methods = ['get', 'patch',]
queryset = User.objects.all()
resource_name = 'users'
excludes = [ 'first_name', 'last_name', 'password' ]
filtering = {
...
}
additional_urls = [
('signup/', 'signup', 'api-signup'),
('signin/', 'signin', 'api-signin'),
]
allowed_fields = ['email',]