用户管理django-tastypie(有角度的)

时间:2014-06-01 17:30:34

标签: django angularjs tastypie

Okey所以我希望使用django(1.6),tastyie和angularjs为我的网站创建非常简单的用户管理。我希望能够登录/注销/退出。我基本上从这里实现了解决方案:How can I login to django using tastypie

我的代码如下:

资源:

from tastypie.resources import ModelResource, ALL, ALL_WITH_RELATIONS
from photod.models import Project, ProjectImage
from tastypie.authorization import DjangoAuthorization,Authorization
from tastypie.authentication import BasicAuthentication,Authentication
from django.contrib.auth.models import User
from django.contrib.auth import authenticate, login, logout
from tastypie import fields
from tastypie.serializers import Serializer
from tastypie.exceptions import BadRequest
from django.db import IntegrityError
from tastypie.http import HttpUnauthorized, HttpForbidden
from django.conf.urls import url
from tastypie.utils import trailing_slash

class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        excludes = ['email', 'password', 'is_active', 'is_staff', 'is_superuser'] 
        serializer = Serializer(formats=['json', 'jsonp'])
        always_return_data = True
        filtering = {
            'username': 'exact',
            'id': ALL_WITH_RELATIONS,
        }

    def prepend_urls(self):
        return [
            url(r"^(?P<resource_name>%s)/login%s$" %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('login'), name="api_login"),
            url(r'^(?P<resource_name>%s)/logout%s$' %
                (self._meta.resource_name, trailing_slash()),
                self.wrap_view('logout'), name='api_logout'),
        ]

    def login(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)
                return self.create_response(request, {
                    'success': True
                })
            else:
                return self.create_response(request, {
                    'success': False,
                    'reason': 'disabled',
                    }, HttpForbidden )
        else:
            return self.create_response(request, {
                'success': False,
                'reason': 'incorrect user information',
                }, HttpUnauthorized )

    def logout(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        if request.user and request.user.is_authenticated():
            logout(request)
            return self.create_response(request, { 'success': True })
        else:
            return self.create_response(request, { 'success': False }, HttpUnauthorized)

lass CreateUserResource(ModelResource):
    class Meta:
        allowed_methods = ['post']
        object_class = User
        resource_name = 'register'
        queryset = User.objects.all()
        authentication = Authentication()
        authorization = Authorization()
        include_resource_uri = False
        fields = ['username', 'id']
        always_return_data = True
    def obj_create(self, bundle, request=None, **kwargs):
        username, password = bundle.data['username'], bundle.data['password']
        try:
            bundle.obj = User.objects.create_user(username, '', password)
        except IntegrityError:
            raise BadRequest('That username already exists')
        return bundle

前端:

photodice.controller('userController', function($scope, $resource, userFactory) {
  $scope.userName = '';
  $scope.userPw = '';
  $scope.Signup = function() {
   var userC = $resource("http://xx.xxx.xxx.xx:xxxx/api/v1/register/");
   var newUser = new userC();
   newUser.username = $scope.userName;
   newUser.password =  $scope.userPw;
   newUser.$save(function (user, headers) {// Success
    userFactory.setUser(user.username, user.id);
    console.log("$save (signUp) success " + JSON.stringify(user));
    $scope.userName = '';//cleanup
    $scope.userPw = '';//cleanup
   }, function (error) {// failure - TODO: add message
    console.log("$save (signUp) failed " + JSON.stringify(error.data.error_message))
   });
  }
$scope.Signin = function() {
var userResource = $resource('http://xx.xxx.xxx.xx:xxxx/api/v1/user/login/');
user = new userResource();
user.username = $scope.userName;
user.password = $scope.userPw;
user.$save(function () {// Success
  userFactory.setUser($scope.userName);
  console.log("$save (signIn) success " + JSON.stringify(user));
  $scope.userName = '';//cleanup
  $scope.userPw = '';//cleanup
}, function (error) {// failure - TODO: add message
  console.log("$save (signIn) failed " + JSON.stringify(error.data.error_message));
});
}
$scope.Signout = function() {
console.log("called signout");
var userResource = $resource('http://xx.xxx.xxx.xx:xxxx/api/v1/user/logout/:user', { user:'@user' });
var user = userResource({user:userFactory.getUser()}, function() {
user.$save(function (user, headers) {// Success
  userFactory.setUser('');
  console.log("$save (signIn) success " + JSON.stringify(user));
}, function (error) {// failure - TODO: add message
  console.log("$save (signIn) failed " + JSON.stringify(error.data.error_message));
});
});
}
});

但我有一些问题和疑问: 首先我可以使用超级用户帐户登录,但我只获得{“success”:true,“$ resolved”:true}作为响应...我应该得到某种令牌或id或更多数据吗?

我可以注册新用户,但他们无法登录,因为我得到了:401(未经授权)

编辑:经过进一步调查后,我注意到虽然我可以注册新用户,但是没有设置任何密码......为什么会这样?

1 个答案:

答案 0 :(得分:2)

1

  

但我有一些问题和疑问:首先我可以登录   超级用户帐户,但我只得到{&#34;成功&#34;:true,&#34; $ resolved&#34;:true} as   响应...我不应该获得某种令牌或id或更多数据吗?

您在登录时所做的是与用户分配请求。您在此处对用户进行了身份验证:user = authenticate(username=username, password=password)并指定该用户在此处请求:login(request, user)。因此,Django现在会在会话期间将request.user识别为该用户。

您尚未在资源中定义身份验证方法,因此是默认方法。它还可以访问匿名用户,因此无需进行身份验证即可访问。一旦您决定要使用哪种身份验证,您就会考虑令牌和内容。 请参阅:Authentication in Tastypie

2

  

我可以注册新用户,但他们无法登录,因为我得到:   401(未经授权)

您最有可能看到这一点,因为您的密码或用户名不正确。 user = authenticate(username=username, password=password)为您user is None提供了eles块。您可以确保在该步骤中打印日志。

3

  

编辑:经过进一步调查,我注意到虽然我可以注册   新用户,没有设置密码......为什么会这样?

我测试了相同的代码并完美运行。确保你在前端没有拼写错误。并打印值为obj_create的日志,以确保它们不会为空。

4

允许会话身份验证非常困难,并且能够解决其他问题。这样就可以获得request.user。 (非常不安全但很简单)

class PasswordAuthentication(Authentication):
    def is_authenticated(self, request, **kwargs):
        """
        Allow get not authenticated users but try assign user to request
        if possible.
        """
        try:
            username, password = request.GET.get('username'), request.GET.get('password')
        except ValueError:
            return True

        if not username or not password:
            return True

        try:
            user = User.objects.get(username=username, password=password)
        except (User.DoesNotExist, User.MultipleObjectsReturned):
            return True

        if not self.check_active(user):
            return True

        request.user = user

        return True


class UserResource(ModelResource):
    class Meta:
        queryset = User.objects.all()
        resource_name = 'user'
        excludes = ['email', 'password', 'is_active', 'is_staff', 'is_superuser'] 
        serializer = Serializer(formats=['json', 'jsonp'])
        authentication = PasswordAuthentication()
        always_return_data = True
        filtering = {
            'username': 'exact',
            'id': ALL_WITH_RELATIONS,
        }

    [...]

    def logout(self, request, **kwargs):
        self.method_check(request, allowed=['get'])
        if request.user and request.user.is_authenticated():
            logout(request)
            return self.create_response(request, { 'success': True })
        else:
            return self.create_response(request, { 'success': False }, HttpUnauthorized)

使用http://xx.xxx.xxx.xx:xxxx/api/v1/user/logout/4/?username=asdf&password=1234

致电后端