Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python REST上的身份验证_Python_Django_Angularjs_Django Rest Framework_Restangular - Fatal编程技术网

Python REST上的身份验证

Python REST上的身份验证,python,django,angularjs,django-rest-framework,restangular,Python,Django,Angularjs,Django Rest Framework,Restangular,更新3:REST API权限:定义视图集时关联适当的权限类 class TopSecretViewSet(mixins.ListModelMixin, viewsets.GenericViewSet): queryset = myModels.TopSecret.objects.all() serializer_class = mySerializers.TopSecretSerializer permission_classes = (myAuth.MyIsAuthen

更新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负载中返回)

原职 编辑:我将此连接到一个PHP遗留应用程序并排运行,直到我可以在未来一年左右完全移植到Python。因此,内置Django身份验证的吸引力没有那么大

我有一个单页web应用程序,它显示一组摘要内容。如果单击内容,系统会提示您登录。我使用屏幕上的div覆盖显示登录表单,我希望将此表单上的数据提交给服务器进行身份验证

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

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

问题2:使用Django Rest框架,我需要协调身份验证和登录服务。我想我应该创建一个自定义身份验证来读取cookie并识别正确的用户和权限。这看起来是一个合理的解决方案吗

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

我的客户端堆栈:AngularJs、RESTangular(它能很好地拾取饼干)和其他不太有趣的片段

我的服务器堆栈:Python 2.7、Django 1.5、Django Rest框架


始终-提前感谢您!

RESTAPI并不意味着您必须使用REST完成所有工作

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


通过这种方式,您可以使用内置的django身份验证,并且仍然使用rest api进行数据验证。无需重新发明您不需要的内容!

我在最初的帖子中一步一步地回答,因为我正在发现解决方案。基本上,这些步骤是

  • 创建一个rest服务来执行身份验证。在使用django rest框架时,我继承了GenericViewet并重写了Create方法来处理POST。我向UI返回了JSON,即表示经过身份验证的用户的响应paylod,并且还转储了一个具有相同对象的cookie。其思想是返回payloa对于那些等待返回响应的控制器来说,d最好插入我的angularjs前端。当应用程序为返回访问者启动时,可以读取cookie,并将其传递给REST请求

  • 创建您自己的身份验证类并将其插入REST框架(在设置中)。在我的示例中,我阅读了cookie并在DB中找到了用户。如果您希望能够关联某些REST API上的权限,则需要创建您自己的权限类(小而简单).在上面的示例中,我只检查实例化的用户类是否是我的用户类的实例-但最终我将检查个人权限

  • 将权限添加到相应的视图集


  • 同意-这是我的退路。在这一点上,这是一种智力上的好奇,而不是手动创建用户,使用django内置功能:
    #####################################################################
    # 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': ''})