Python Django - Can't pickle <type 'cStringIO.StringO">



我正在尝试使用芹菜通过ajax处理用户登录请求。

这是我的用户登录名:

#Login the user using Ajax
def ajax_loginOrRegisterUser(request):
    #Set a test cookie
    request.session.set_test_cookie()
    #Test if the request is POST, otherwise fail
    if request.method == 'POST':
        #Calls celery to do the heavy lifting
        result = userLoginCheck.delay(request)
        data = result.get(timeout=30)
        #Return the response
        return HttpResponse(data)
    else:
        #Log the System, send an alert message to the admin
        logger = logging.getLogger('views.logger.login')
        logger.error("Login User should not be GET")
        logger.info("Unknown User returning Invalid")
        #Send an invalid modal to the user
        return HttpResponse("Invalid")

这很简单,基本上是这样的:

  1. 检查这是否是POST请求,如果是,则继续
  2. 使用Celery对用户进行身份验证、注册用户并报告任何错误消息
  3. 它将返回一个字符串,该字符串作为HttpResponse传递给jQuery

那么日志记录部分就更复杂了:

#Celery should look at login user request, and make appropriate decisions
@shared_task
def userLoginCheck(request):
        #Get logger
        logger = logging.getLogger('views.logger.login')
        #Set user name and type
        username = ""
        type = ""
        #Try to get the user's username
        try:
            username = request.POST['username']
        except:
            logger.error("Error occured in Signing/Registering user, cannot find username")
            logger.info("Unknown User returning Invalid")
            return ("Invalid")
        #See what type of request we are making, signin or register
        try:
            type = request.POST['type']
            #Test if cookie works, otherwise inform the user, and fail login
            if request.session.test_cookie_worked():
                request.session.delete_test_cookie()
                #Try to see username, password, rememberMe is missing or not
                try:
                    username = str(request.POST['username'])
                    password = request.POST['password']
                    rememberMe = request.POST['rememberMe']
                    #If it is a signin type
                    if(type == "signin"):
                        ##############USER BASED AUTHENTICATION SYSTEM#####################
                        #Test for the user's public IP or best matched IP to see if it is banned
                        realIP = str(get_real_ip(request))
                        IP = str(get_ip(request))
                        #Get their realIP, and see if it matches, if they have over 10 accounts, then they are banned
                        try:
                            SusIP = suspiciousIP.objects.get(pk=realIP)
                            if(SusIP.count >= 10):
                                logger.info("User:" + str(username) + " has a banned real IP")
                                logger.info("User:" + str(username) + " returning Banned")
                                return ("Banned")
                        except:
                            pass
                        #Get their IP, and see if it matches, if they have over 10 accounts, then they are banned
                        try:
                            SusIP = suspiciousIP.objects.get(pk=IP)
                            if(SusIP.count >= 10):
                                logger.info("User:" + str(username) + " has a banned IP")
                                logger.info("User:" + str(username) + " returning Banned")
                                return ("Banned")
                        except:
                            pass
                        #Test the current user's blockedList
                        #2 conditions, if lockedTemp = True, then it is temporary locked until user has unlocked it
                        #by clicking the unlock email
                        #The other condition is whether tries > 5, and violations <= 5 (at 5th violations, the lockedTemp = true)
                        #then the user would need to wait until the time is over (900 seconds), which increases by each violations
                        try:
                            #Get the user's blocked list if available
                            userObject = blockedList.objects.get(pk=str(username))
                            currentDateTime = datetime.datetime.now()
                            objectDateTime = 0
                            #Try to see if the objectDateTime is available (meaning a date is there)
                            try:
                                objectDateTime = datetime.datetime.strptime(str(userObject.dateTime), "%Y-%m-%d %H:%M:%S.%f")
                            except:
                                pass
                            #Load the locked, tries, and violations
                            lockedTemp = userObject.lockedTemp
                            tries = userObject.tries
                            violations = userObject.violations
                            #if LockedTemp == True, then it means the user is currently locked, can only be unlocked by email
                            if(lockedTemp == "True"):
                                logger.info("User:" + str(username) + " is temp locked")
                                logger.info("User:" + str(username) + " returning tempLock")
                                return ("tempLock")
                            elif (tries >= 5 and violations <= 5 and lockedTemp != "True"):
                                #The user is not locked, 
                                timeDifferenceSeconds = (currentDateTime - objectDateTime).total_seconds()
                                #if tries > 5, and violations < 5, and locked is false, then we test whether the time difference is > 900 seconds
                                if(timeDifferenceSeconds > (900 * violations)):
                                    #If over > 900 seconds, then we will reset tries
                                    userObject.tries = 0
                                    userObject.save()
                                    logger.info("User:" + str(username) + " is unlocked, with tries:" + str(tries) + ", violations:" + str(violations))
                                else:
                                    #If < 900 seconds, then we will keep locking the user
                                    logger.info("User:" + str(username) + " is currently locked, with tries:" + str(tries) + ", violations:" + str(violations))
                                    logger.info("User:" + str(username) + " returning Locked")
                                    return ("Locked")
                        except:
                            pass
                        ##############USER BASED AUTHENTICATION SYSTEM#####################
                        ##############SESSION BASED##################
                        #Initialize tries, to be used later on
                        # tries = "0"
                        # try:
                            # tries = request.session['tries']
                        # except:
                            # pass
                        # #If tries > 5 times
                        # if(int(tries) >= 5):
                            # timeNow = request.session['locked_time']
                            # timeDifferenceSeconds = (datetime.datetime.now() - datetime.datetime.strptime(timeNow, "%Y-%m-%d %H:%M:%S.%f")).total_seconds()
                            # #See if the difference is greater than 15 minutes, otherwise lock
                            # if(timeDifferenceSeconds > 900):
                                # request.session['tries'] = str(0)
                                # logger.info("User:" + str(username) + " is unlocked")
                            # else:
                                # logger.info("User:" + str(username) + " is currently locked")
                                # logger.info("User:" + str(username) + " returning Locked")
                                # return ("Locked")
                        ##############SESSION BASED##################
                        #See if the user is activated yet (through email)
                        try:
                            userActivatedObject = userActivated.objects.get(pk=username)
                            if(userActivatedObject.activation == "True"):
                                logger.info("User:" + str(username) + " is activated")
                            else:
                                logger.info("User:" + str(username) + " is not activated yet")
                                return ("Activation")
                        except:
                            pass
                        logger.info("UserName:" + username + " is trying to login")
                        user = authenticate(username=username, password=password)
                        #If the user does exist
                        if user is not None:
                            #And is active
                            if user.is_active:
                                login(request, user)
                                logger.info("User:" + str(username) + "is active, and logged in")
                                #See if the user's remember me is checked, if it is not checked, then
                                #the session cookie will automatically expire when the browser closes
                                if(rememberMe == "true"):
                                    request.session.set_expiry(86400)
                                    logger.info("User:" + str(username) + " has set their expiration to 1 day")
                                else:
                                    request.session.set_expiry(0)
                                    logger.info("User:" + str(username) + " has set their expiration to expire when browser closes")
                                #See if the user is marked in blockedList, if true, then delete their row
                                try:
                                    userObject = blockedList.objects.get(pk=username)
                                    userObject.delete()
                                    logger.info("User:" + str(username) + " is in blockedList, removing their entry")
                                except:
                                    logger.info("User:" + str(username) + " is NOT in blockedList")

                                #See if the user's real IP is marked in suspicious IP, if true, then remove their entry
                                try:
                                    SusIP = suspiciousIP.objects.get(pk=realIP)
                                    SusIP.delete()
                                    logger.info("User:" + str(username) + " is in suspicious real IP, removing their entry")
                                except:
                                    logger.info("User:" + str(username) + " is NOT in real suspeciousIP")
                                #See if the user's IP is marked in suspicious IP, if true, then remove their entry
                                try:
                                    SusIP = suspiciousIP.objects.get(pk=IP)
                                    SusIP.delete()
                                    logger.info("User:" + str(username) + " is in suspicious IP, removing their entry")
                                except:
                                    logger.info("User:" + str(username) + " is NOT in suspeciousIP")
                                logger.info("User:" + str(username) + " returning index.html")
                                return ('index.html')
                            else:
                                logger.info("User:" + str(username) + "is not active, and will not be logged in")
                                logger.info("User:" + str(username) + " returning Invalid")
                                return ("Invalid")
                        else:
                            ##############USER BASED AUTHENTICATION SYSTEM#####################
                            try:
                                #Get their current object, if exists, and increase their tries
                                userObject = blockedList.objects.get(pk=username)
                                userObject.tries += 1
                                userObject.save()
                                print "After:" + str(userObject.tries)
                                #If their tries >= 5, then lock them temporary, and increase violations
                                if(userObject.tries >= 5):
                                    logger.info("User:" + str(username) + " is not valid, current tries:" + str(userObject.tries) + " and will be locked")
                                    userObject.violations += 1
                                    userObject.dateTime = str(datetime.datetime.now())
                                    userObject.save()
                                    #If violations >= 5, then we will tempLock, and can only be unlocked by email
                                    if(userObject.violations >= 5):
                                        print "I'm here"
                                        logger.info("User:" + str(username) + " is not valid, will get TempLocked")
                                        userObject.lockedTemp = "True"
                                        userObject.dateTime = ""
                                        userObject.tries = 0
                                        userObject.violations = 0
                                        userObject.save()
                                        #Get their suspicious Real IPs, and increase them, or make a new one
                                        try:
                                            susIP = suspiciousIP.objects.get(pk=realIP)
                                            susIP.count += 1
                                            susIP.save()
                                            logger.info("User:" + str(username) + " has a suspeciousIP:" + str(susIP.IP) + " current count:" + str(susIP.count))
                                        except:
                                            if (realIP is not None and realIP != "None"):
                                                susIP = suspiciousIP(pk=realIP, count=1)
                                                susIP.save()
                                                logger.info("User:" + str(username) + " has a new suspeciousIP:" + str(realIP))
                                        #Get their suspicious IPs, and increase them, or make a new one
                                        try:
                                            susIP = suspiciousIP.objects.get(pk=IP)
                                            susIP.count += 1
                                            susIP.save()
                                            logger.info("User:" + str(username) + " has a suspeciousIP:" + str(susIP.IP) + " current count:" + str(susIP.count))
                                        except:
                                            if IP is not None:
                                                susIP = suspiciousIP(pk=IP, count=1)
                                                susIP.save()
                                                logger.info("User:" + str(username) + " has a new suspeciousIP:" + str(IP))
                                        logger.info("User:" + str(username) + " returning tempLock")
                                        logger.info("User:" + str(username) + " returning tempLock")
                                        return ("tempLock")
                                    logger.info("User:" + str(username) + " returning Locked")
                                    return ("Locked")
                            except:
                                #Invalid password typed, and the username that was typed is not found in our blockedList
                                #Then we will create a new one
                                #Setup an invalid password violation in the database
                                newUsername = str(username)
                                newRealIP = realIP
                                newIP = IP
                                newDateTime = ""
                                newTries = 1
                                newViolations = 0
                                newLockedTemp = "False"
                                #Create a user blockedList
                                newUserObject = blockedList(username=newUsername, realIP=newRealIP, IP = newIP,
                                                            dateTime = newDateTime, tries = newTries, violations = newViolations,
                                                            lockedTemp = newLockedTemp)
                                #Save the row
                                newUserObject.save()
                            logger.info("User:" + str(username) + " returning Invalid")
                            return ("Invalid")
                            ##############USER BASED AUTHENTICATION SYSTEM#####################

                            ##############SESSION BASED##################
                            #if the user fails in providing the correct username/password, increment tries
                            # try:
                                # tries = request.session['tries']
                                # num = int(tries) 
                                # num += 1
                                # tries = str(num)
                                # request.session['tries'] = str(tries)
                            # except:
                                # tries = 0
                                # request.session['tries'] = str(tries)
                            # #If tries > 5, then we will lock
                            # if(int(tries) >= 5):
                                # logger.info("User:" + str(username) + " is not valid, current tries:" + str(tries) + " and will be locked")
                                # request.session['locked_time'] = str(datetime.datetime.now())
                                # logger.info("User:" + str(username) + " returning Locked")
                                # return ("Locked")
                            # else:
                                # logger.info("User:" + str(username) + " is not valid, current tries:" + str(tries))
                                # logger.info("User:" + str(username) + " returning Invalid")
                                # return ("Invalid")
                            ##############SESSION BASED##################
                    elif(type == "register"):
                        #Get the logger
                        logger = logging.getLogger('views.logger.register')
                        #Test their session to see if they are already registered
                        registered = ""
                        try:
                            registered = request.session['registered']
                        except:
                            registered = "notRegisteredAlready"
                        #If not registered already, then register the user
                        if(registered == "notRegisteredAlready"):
                            try:
                                #Get the password verdict (strength of password), implemented by zxcvbn
                                passwordVerdict = ""
                                try:
                                    passwordVerdict = request.POST['passwordVerdict']
                                except Exception as e:
                                    #Cannot register the user, possibly failed at user.save(), where the user already existed
                                    logger.info("Error:" + str(e.args))
                                    logger.info("User:" + str(username) + " cannot register, problem with getting the verdict")
                                    logger.info("User:" + str(username) + " returning Invalid")
                                    #Send an invalid modal to the user
                                    return ("Invalid")
                                #Test the user's verdict
                                if testVerdict(passwordVerdict):
                                    #Log the System
                                    logger.info("The new user:" + username + " passes password strength checking")
                                else:
                                    #Log the System
                                    logger.info("The new user:" + username + " password is too weak")
                                    #Send an invalid modal to the user
                                    return ("Invalid")
                                #Log the user
                                logger.info("User:" + str(username) + " checking for special formats")
                                if(checkSpecialCharacters(username) == True and checkHPEmail(username) == True and checkLengthUsername(username) == True and checkSpecialUsernames(username) == True):
                                    #Log the user
                                    logger.info("User:" + str(username) + " passed username policies")
                                    logger.info("User:" + str(username) + " is going to register a new account")
                                    #Create the user, and make a new activationObject, and set to false
                                    user = User.objects.create_user(username, username, password)
                                    user.backend='django.contrib.auth.backends.ModelBackend'
                                    user.is_active = True
                                    user.save()
                                    #Send a registration email
                                    sendRegistrationEmail(user)
                                    #Update the session so it is registered
                                    request.session['registered'] = "registeredAlready"
                                    #Log the system
                                    logger.info("User:" + str(username) + " has successfully registered")
                                    logger.info("User:" + str(username) + " returning Valid")
                                    #Return valid to jQuery
                                    return ("ValidRegistration")
                                else:
                                    #Log the user
                                    logger.info("Test for username policies:" + str(username) + " failed")
                                    #Return invalid to jQuery
                                    return ("Invalid")
                            except Exception as e:
                                #Cannot register the user, possibly failed at user.save(), where the user already existed
                                logger.info("Error:" + str(e.args))
                                logger.info("User:" + str(username) + " cannot register, possibly the name already existed")
                                logger.info("User:" + str(username) + " returning Invalid")
                                #Send an invalid modal to the user
                                return ("Invalid")
                        else:
                            #The user has already registered an account, according to the session
                            logger.info("User:" + str(username) + " cannot register, possibly the name already registered")
                            logger.info("User:" + str(username) + " returning Invalid")
                            #Send an invalid modal to the user
                            return ("Invalid")
                    else:
                        #This else statement is only true when type = "unknown", where the user might have been fiddling with javascript
                        logger.info("User:" + username + " has an unknown type")
                        logger.info("User:" + str(username) + " returning Invalid")
                        #Send an invalid modal to the user
                        return ("Invalid")
                except MultiValueDictKeyError:
                    #This exception comes from we cannot retrieve username or password from the user
                    logger.info("The user:" + str(username) + " have missing forms")
                    logger.info("User:" + str(username) + " returning Invalid")
                    #Send an invalid modal to the user
                    return ("Invalid")
                except Exception as e:
                    #This exception comes from we a serious error AFTER we got the user's username and password
                    logger.error("Error occured in Signing/Register user:" + str(username))
                    logger.error("Error:" + str(e.args))
                    logger.error("User:" + str(username) + " returning Invalid")
                    #Send an invalid modal to the user
                    return ("Invalid")
            else:
                #This else statement is only true when the user does not support cookies
                #Which in case I need
                logger.info("The user:" + str(username) + " does not have cookies enabled")
                logger.info("User:" + str(username) + " returning Invalid")
                #Send an invalid modal to the user
                return ("Invalid")
        except Exception as e:
            #This exception is only true when cannot identify the "type" which is from jQuery ajax
            logger.error("Error:" + str(e.args))
            logger.error("Error occured with user:" + str(username) + " cannot detect login/register type")
            logger.error("User:" + str(username) + " returning Invalid")
            #Send an invalid modal to the user
            return ("Invalid")

它执行以下几个步骤:

  1. 检查用户是否在IP方面被禁止
  2. 检查该特定用户是否已激活
  3. 检查用户是否存在

如果用户不存在:

  1. 记录用户的行为,并对用户名和IP进行计数
  2. 经过特定计数后,用户名将被标记并禁止访问
  3. 如果这个特定的IP导致至少5个用户名被标记,那么禁止他的IP

如果用户想要注册:

  1. 签入会话,无论用户是否已注册
  2. 如果没有,那么我会注册用户,并向用户发送电子邮件,这样用户就可以使用它来激活其帐户

我得到的错误是:

无法pickle:属性查找cStringIO.StringO失败

然而,我不确定在哪里引发了这个异常

有人知道为什么会发生这种情况吗,或者是否有办法找到这种错误发生的地方?

Celery使用pickle作为默认的序列化格式,因此不能pickle Django的请求对象。看看这个和这个类似的问题。

相关内容

  • 没有找到相关文章

最新更新