1

这是一个多部分的问题,我一直在使用 Google App Engine 编写博客,为了方便我为包含主题和文本的博客创建了一个数据存储类。我想练习实现用户注册,因此为包含用户名、密码哈希、电子邮件和创建日期的用户创建了另一个类

  • 这两个类在应用程序引擎上创建实体并显示在仪表板上,但是我的用户表(由于它是 NoSql 实现,我不确定如何调用它)没有显示在我的本地开发服务器仪表板上

  • 当我在用户表上运行查询时,即使用户名从未注册过,它也会返回 true。

  • 我还实现了一个登录功能,它总是返回用户名或密码无效的消息,当然只有当它们无效时才会出现,我知道当我输入它们时它们不是。

这是我的数据存储实体代码

class Blog(db.Model):
subject = db.StringProperty(required = True)
blog = db.TextProperty(required = True)
time_created = db.DateTimeProperty(auto_now_add = True)
day_created = db.DateProperty(auto_now_add = True)

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

这是注册新用户的功能

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 = db.GqlQuery("SELECT username FROM Users WHERE username='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 Login(BlogHandler):
def get(self):
    self.render('login-form.html')

def post(self):
    username = self.request.get('username')
    password = self.request.get('password')

    u = User.login(username, password)
    if u:
        self.login(u)
        self.redirect('/blog')
    else:
        msg = 'Invalid login'
        self.render('login-form.html', error = msg)

这是我继承 webapp2 类的 BaseHandler 函数

class BaseHandler(webapp2.RequestHandler):
    def render(self, template, **kw):
        self.response.out.write(render_str(template, **kw))

    def write(self, *a, **kw):
        self.response.out.write(*a, **kw)

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

    def read_secure_cookie(self, name):
        cookie_val = self.request.cookies.get(name)
        return cookie_val and check_secure_val(cookie_val)

    def login(self, user):
        self.set_secure_cookie('user_id', str(user.key().id()))

    def logout(self):
        self.response.headers.add_header('Set-Cookie', 'user_id=; Path=/')

这些是我用来散列和加盐 cookie 和密码的较小函数

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

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

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

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())

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

1 回答 1

1

您获取用户的查询是错误的:

这个:

u = db.GqlQuery("SELECT username FROM Users WHERE username='self.username'")

应该变成这样的东西:

u = db.GqlQuery("SELECT username FROM Users WHERE username = :1", self.username)

看看文档

于 2013-07-05T09:55:11.343 回答