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(未经授权)
编辑:经过进一步调查后,我注意到虽然我可以注册新用户,但是没有设置任何密码......为什么会这样?
答案 0 :(得分:2)
但我有一些问题和疑问:首先我可以登录 超级用户帐户,但我只得到{&#34;成功&#34;:true,&#34; $ resolved&#34;:true} as 响应...我不应该获得某种令牌或id或更多数据吗?
您在登录时所做的是与用户分配请求。您在此处对用户进行了身份验证:user = authenticate(username=username, password=password)
并指定该用户在此处请求:login(request, user)
。因此,Django现在会在会话期间将request.user
识别为该用户。
您尚未在资源中定义身份验证方法,因此是默认方法。它还可以访问匿名用户,因此无需进行身份验证即可访问。一旦您决定要使用哪种身份验证,您就会考虑令牌和内容。 请参阅:Authentication in Tastypie
我可以注册新用户,但他们无法登录,因为我得到: 401(未经授权)
您最有可能看到这一点,因为您的密码或用户名不正确。 user = authenticate(username=username, password=password)
为您user is None
提供了eles
块。您可以确保在该步骤中打印日志。
编辑:经过进一步调查,我注意到虽然我可以注册 新用户,没有设置密码......为什么会这样?
我测试了相同的代码并完美运行。确保你在前端没有拼写错误。并打印值为obj_create
的日志,以确保它们不会为空。
允许会话身份验证非常困难,并且能够解决其他问题。这样就可以获得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