【问题标题】:Tastypie sign-in美味签到
【发布时间】:2013-04-27 15:15:03
【问题描述】:

我想创建登录资源,但我不知道怎么做:(

我有我的 UserResource,我认为最好使用 LoginResource 作为登录方法。

    class UserResource(ModelResource):
        foreign_key = ForeignKey(ForeignResource, 'foreign_key', null=True)
        ...
        class Meta:
            queryset = User.objects.all()
            allowed_methods = ['post']
            resource_name = 'user'
            authentication = ApiKeyAuthentication()
            authorization = Authorization()

        def obj_create(self, bundle, **kwargs):
            try:
                bundle = super(UserResource, self).obj_create(bundle, **kwargs)
                bundle.obj.set_password(bundle.data.get('password'))
                bundle.obj.save() 
            except IntegrityError:
                raise BadRequest(_("A user with that username already exists."))
            return bundle

那么我应该怎么做 LoginResource 实现,这就是我已经走了多远:)

class LoginResource(ModelResource):
    pass

我希望发送(发布/获取)/v1/login/ 用户名和密码,然后如果登录成功返回用户对象,就像我有 GET /v1/user/1/ 一样。

提前致谢!

【问题讨论】:

    标签: django tastypie


    【解决方案1】:

    你需要在这里做一些事情,

    1. 使用授权类将用户对象限制为与 request.user 相关的对象。
    2. 在资源类上使用 prepend_urls 来附加登录和注销视图

    例如:https://gist.github.com/airtonix/5473873

    其中一些代码可能会让比我更有能力的人感到非常冒犯,但这绝对是你想要前进的方向。

    【讨论】:

    • 虽然你可以这样做,但我突然想到,简单地使用 Apikey 身份验证和授权类来限制对记录的访问会更好。
    【解决方案2】:

    这样的东西应该可以工作(未经测试):

    class UserResource(ModelResource):
        class Meta:
            queryset = User.objects.all()
            fields = ['first_name', 'last_name', 'email']
            allowed_methods = ['get', 'post']
            resource_name = 'user'
    
        def override_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'])
    
            username = request.POST.get('username', '')
            password = request.POST.get('password', '')
    
            user = authenticate(username=username, password=password)
            if user:
                if user.is_active:
                    login(request, user)
                    kwargs = {'pk': user.id, 'api_name': u'v1', 'resource_name': u'user'}
                    return self.get_detail(request, **kwargs)
                else:
                    return HttpResponse(status=401)
            else:
                return HttpResponse(status=401)
    
        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)
    

    那么你可以这样做:

    curl --dump-header - -H "Content-Type: application/json" -X POST --data '{"username" : "me", "password": "l33t"}' http://localhost:8000/api/v1/user/login/
    

    它应该在成功登录时为您提供用户对象。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-19
      • 2014-06-02
      • 2012-10-30
      • 2014-01-23
      • 1970-01-01
      • 2012-04-18
      • 2012-04-03
      • 1970-01-01
      相关资源
      最近更新 更多