Python:NoneType错误 - “强制转换为Unicode:需要字符串或缓冲区,找到NoneType”

时间:2013-07-01 17:47:52

标签: python google-app-engine webapp2

我正在使用Google App Engine并使用数据存储区为用户创建一个表格,其中包含实体用户名,密码哈希值,电子邮件和加入日期。但是,当我运行一个函数来注册用户时,哈希密码的函数返回NoneType错误。

我试图查找错误,但表单正在发布值,我可以从标题中获取它们。

这是处理注册的代码段

def make_salt():
chars = string.ascii_uppercase + string.ascii_lowercase + string.ascii_digits
return ''.join(random.choice(chars) for x in range(5))

def make_pw_h(name, pw, salt = None):
    if salt:
        salt = make_salt()
 return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())

def check_pw_h(name, pw, h):
     h = h.split(',')[1]
    return h == make_pw_h(name, pw, h)

class Users(db.Model):
    username = db.StringProperty(required = True)
    pw_hash = db.StringProperty(required = True)
    emai = db.StringProperty()
    user_since = db.DateTimeProperty(auto_now_add = True)

@classmethod
def by_id(cls, uid):
    return Users.get_by_id(uid)

@classmethod
def by_name(cls, name):
    user = Users.all().filter('name = ', name).get()
    return user

@classmethod
def register(cls, name, pw, email = None):
    pw_h = make_pw_h(name, pw)
    return Users(username = name,
                pw_hash = pw_h,
                email = email)

@classmethod
def login(cls, name, pw):
    u = cls.by_name(name)
    if u and check_pw(pw):
        return u        

def make_secure_val(s):
    return '%s|%s' % (val, hmac.new(secret, val).hexdigest())

def check_secure_val(sec_val):
    val = val.split('|')[0]
    if sec_val == make_secure_val(val):
        return val

class BaseHandler(webapp2.RequestHandler):

#this function uses the render_str funcion to display the html form in the browser
def render(self, template, **kw):
    self.response.out.write(render_str(template, **kw))

#this funcion is a simple function using the template engine to write out the required data with 
#any extra parameters
def write(self, *a, **kw):
    self.response.out.write(*a, **kw)

def set_sec_coki(self, name, val):
    sec_val = make_secure_val(val)
    self.response.headers.add_cookie('Set-Cookie', "%s=%s; Path=/" % (name, sec_val))

def read_sec_coki(self, name):
    coki_val = self.request.cookies.get(name)
    return coki_val and check_secure_val(coki_val)

def Initialize(self, *a, **kw):
    webapp2.RequestHandler.Initialize(self, *a, **kw)
    uid = self.read_sec_coki('user-id')
    self.user = uid and Users.by_id(int(uid))


class Signup(BaseHandler):
def get(self):
    self.render("signup-form.html")

def post(self):
    have_error = False
    self.username = self.request.get('username')
    self.password = self.request.get('password')
    self.verify = self.request.get('verify')
    self.email = self.request.get('email')

    params = dict(username = self.username,
                  email = self.email)

    if not valid_username(self.username):
        params['error_username'] = "That's not a valid username."
        have_error = True

    if not valid_password(self.password):
        params['error_password'] = "That wasn't a valid password."
        have_error = True
    elif self.password != self.verify:
        params['error_verify'] = "Your passwords didn't match."
        have_error = True

    if not valid_email(self.email):
        params['error_email'] = "That's not a valid email."
        have_error = True

    if have_error:
        self.render('signup-form.html', **params)
    else:
        u = Users.by_name(self.username)
        if u:
            msg = "User already exists"
            self.render('signup-form.html', error_username = msg)
        else:
            sing_user = Users.register(self.username, self.password, self.email)
            sing_user.put()

            self.login(sing_user)


            self.set_sec_coki('user-id', sing_user.key().id())

            self.redirect('/welcome')


class WelcomePage(BaseHandler):
def get(self):
    coki_val = read_sec_coki('user-id')
    u_id = coki_val.check_secure_val(coki_val)
    part_usr = u_id.by_id(int(u_id))
    name = part_usr.username
    self.render("welcome.html", username = name)

当我尝试通过表单

注册新用户时,这是我得到的错误堆栈
Traceback (most recent call last):
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1536, in     __call__
rv = self.handle_exception(request, response, e)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1530, in __call__
rv = self.router.dispatch(request, response)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1278, in default_dispatcher
return route.handler_adapter(request, response)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 1102, in __call__
return handler.dispatch()
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 572, in dispatch
return self.handle_exception(e, self.app.debug)
File "/home/bigb/google_projects/google_appengine/lib/webapp2/webapp2.py", line 570, in dispatch
return method(*args, **kwargs)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 197, in post
sing_user = Users.register(self.username, self.password, self.email)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 55, in register
pw_h = make_pw_h(name, pw)
File "/home/bigb/google_projects/my-ramblings/blog.py", line 32, in make_pw_h
return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())
TypeError: coercing to Unicode: need string or buffer, NoneType found

1 个答案:

答案 0 :(得分:2)

您只使用两个参数make_pw_h()name来呼叫pw。您将salt保留为默认值None

def make_pw_h(name, pw, salt = None):
    if salt:
        salt = make_salt()
    return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())

这意味着if salt:测试为False,最后您将None传递给hashlib.sha256

也许您打算测试salt是否设置:

def make_pw_h(name, pw, salt=None):
    if salt is None:
        salt = make_salt()
    return "%s,%s" % (salt, hashlib.sha256(name + pw + salt).hexdigest())