3

更新 3:REST API 权限:定义视图集时关联适当的权限类...

class TopSecretViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = myModels.TopSecret.objects.all()
    serializer_class = mySerializers.TopSecretSerializer
    permission_classes = (myAuth.MyIsAuthenticated,)

更新 2:REST 身份验证

编辑与用户一起返回权限对象

设置.py

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': (
       'app.authentication.MyAuthentication',
    )

身份验证.py

class MyIsAuthenticated(BasePermission):
    """
    Allows access only to authenticated, if it is AnnoymousUser we 
    don't allow access.  There will be more code here - but this is 
    good for the example
    """

    def has_permission(self, request, view):
        if request.user and isinstance(request.user, myModels.User):
            return True
        return False


######################################################
# TODO: return the apropiate permissions
######################################################    
class MyAuthentication(authentication.BaseAuthentication):
    def authenticate(self, request):
        cookies = request.COOKIES
        if 'user' in cookies:
            userCookie = request.COOKIES['user']
            userJson = base64.b64decode(userCookie)
            userDict = json.loads(userJson)
            userId = userDict['user_id']

            if not userId:
                return None

            try:
                user =myModels.User.objects.get(user_id=userId)
            except myModels.User.DoesNotExist:
                raise exceptions.AuthenticationFailed('No such user')

            return (user, MyIsAuthenticated)
        return None

更新:解决方案

django restframework 视图集:

编辑添加了用户对象的 base64 编码 cookie(也在 JSON 有效负载中返回

#####################################################################
# handles two REST APIs GET/list users (through the mixin and) in 
#     accordance to the rules of the UserLoginSerializer
#     the POST/create - and while I don't like handling this in the
#     create method, this is the post of the login credentials
#####################################################################
class UserViewSet(mixins.ListModelMixin, viewsets.GenericViewSet):
    queryset = myModels.User.objects.all()
    serializer_class = mySerializers.UserLoginSerializer

    def set_cookie(response, key, value, days_expire=7, host=''):
        if days_expire is None:
            max_age = 1 * 24 * 60 * 60  #1 day
        else:
            max_age = days_expire * 24 * 60 * 60
        expires = datetime.strftime(datetime.utcnow() + timedelta(seconds=max_age),"%a, %d-%b-%Y %H:%M:%S GMT")

        host = host.split(':')[0]

        response.set_cookie(key, value, max_age=max_age, expires=expires, domain=host)
        return response

    def create(self, request):
        login_email = request.DATA['email']
        login_password = request.DATA['password']
        login_password = login_password
        user = myModels.User.objects.get(email=login_email)

        md5 = hashlib.md5()
        md5.update(login_password)
        login_password_md5 = unicode(md5.hexdigest())

        if (user and login_password_md5 == user.password):

            user.last_login = datetime.now()
            user.save()

            role = 4 #verfied user
            responseData = {
                    'user_id': user.user_id
                    , 'firstName': user.firstname
                    , 'lastName': user.lastname
                    , 'email': login_email
                    , 'role': role
            }

            return  set_cookie(
                Response(responseData)
                , 'user'
                , base64.b64encode(json.dumps(responseData, ensure_ascii=False))
                , days_expire=1
                , host = request.META['HTTP_HOST'])

        else:
            role  = 1 #anonymous
            return Response({'email': login_email, 'role': role, 'message': 'Unknown Email or Incorrect Password'
                , 'user_id':  -1, 'first_name': '' , 'last_name': ''})

原帖

编辑我将它连接到一个 PHP 遗留应用程序以并行运行,直到我可以在明年左右完全移植到 Python。因此,内置 Django Authentication 的吸引力并不那么吸引人

我有一个单页网络应用程序,它显示了一堆预告内容。如果单击内容,则会提示您登录。我在屏幕上使用 div 覆盖显示登录表单,并且我想将此表单上的数据提交到服务器进行身份验证。

我们的网站目前通过 HTTPS 运行,所以我认为一个简单的解决方案是目前最好的。

问题 1:登录服务:我正在考虑通过 POST REST 请求执行登录,但我不确定这是正确的方法 - 或者真的 - 如果有更好的方法。

问题 2:使用 Django-Rest-Framework 我需要协调身份验证和登录服务。我在想我会创建一个自定义身份验证来读取 cookie 并识别正确的用户和权限。这似乎是一个合理的解决方案?

问题3:饼干?我应该在哪里写cookie?我应该将它作为登录服务的一部分嵌入服务器的响应中,还是应该在成功登录后将其写入 js/客户端。我认为前者可能是更好的方法,并且可以允许我将来对 cookie 进行加密 [de],将所有代码放在一个地方(服务器)。有人认为在成功登录后在 javascript 端写入 cookie 更好吗?

我的客户端堆栈:AngularJs、RESTangular(它很好地拾取 cookie)和其他不太有趣的部分

我的服务器堆栈:Python 2.7、Django 1.5、Django-Rest-Framework

总是-提前谢谢你!

4

2 回答 2

0

REST api 并不意味着您必须使用休息来做所有事情。

我建议对您正在使用和操作的数据使用 REST 接口,并使用自定义处理程序进行身份验证。

这样,您可以使用内置的 django 身份验证,并且仍然使用您的 rest api 来获取数据。无需重新发明您不需要的东西!

于 2013-10-08T15:41:03.623 回答
0

当我发现解决方案时,我逐步在原始帖子中回答。基本上这些步骤是

  1. 创建一个休息服务来执行身份验证。在使用 django rest 框架时,我继承了 GenericViewet 并覆盖了 create 方法来处理 POST。我将 JSON 返回到 UI,即代表经过身份验证的用户的响应 Paylod,并且我还转储了具有相同对象的 cookie。想法是返回有效负载最好插入我的 angularjs 前端,以供那些等待返回响应的控制器使用。当应用程序为回访者启动时,可以读取 cookie,并且在 REST 请求中传递它。

  2. 创建您自己的身份验证类并将其插入 REST 框架(在设置中)。在我的情况下,我读取了 cookie 并在数据库中找到了用户。如果您希望能够关联某些 REST API 的权限,那么您需要创建自己的权限类(小而简单)。在我上面的例子中,我只检查实例化的用户类是我的用户类的一个实例——但最终我会检查个人权限。

  3. 将权限添加到适当的视图集

于 2013-10-10T15:17:04.260 回答