2011-06-29 73 views
18

我想知道是否有人知道在Tornado中实现登录/注册页面的任何示例代码或教程?我看到了它的例子,但它们看起来非常像facebook/oauth。Tornado登录示例/教程

回答

31

下面是一个简单的示例处理程序,它需要一个包含用户名/密码表单的login.html模板。我没有注册示例,但它非常类似,在您验证输入并插入用户记录而不是验证的帖子中。

class BaseHandler(tornado.web.RequestHandler): 

    def get_login_url(self): 
     return u"/login" 

    def get_current_user(self): 
     user_json = self.get_secure_cookie("user") 
     if user_json: 
      return tornado.escape.json_decode(user_json) 
     else: 
      return None 

class LoginHandler(BaseHandler): 

    def get(self): 
     self.render("login.html", next=self.get_argument("next","/")) 

    def post(self): 
     username = self.get_argument("username", "") 
     password = self.get_argument("password", "") 
     # The authenticate method should match a username and password 
     # to a username and password hash in the database users table. 
     # Implementation left as an exercise for the reader. 
     auth = self.db.authenticate(username, password) 
     if auth: 
      self.set_current_user(username) 
      self.redirect(self.get_argument("next", u"/")) 
     else: 
      error_msg = u"?error=" + tornado.escape.url_escape("Login incorrect.") 
      self.redirect(u"/login" + error_msg) 

    def set_current_user(self, user): 
     if user: 
      self.set_secure_cookie("user", tornado.escape.json_encode(user)) 
     else: 
      self.clear_cookie("user") 

class LogoutHandler(BaseHandler): 

    def get(self): 
     self.clear_cookie("user") 
     self.redirect(u"/login) 
11

我开始使用科尔的例子,但意识到我访问这可能不是同样的事情,我们的Web应用程序的帐户数据库中创建一个帐户。

我改变了上面的例子使用bcrpyt。现在,用户与我们的webapp的连接不同于我们的webapp与数据库的连接。 My sample app on github

注:bcrpyt是计算繁重并且将阻止IO循环

class BaseHandler(tornado.web.RequestHandler): 

    def get_login_url(self): 
    return u"/login" 

    def get_current_user(self): 
    user_json = self.get_secure_cookie("user") 
    if user_json: 
     return tornado.escape.json_decode(user_json) 
    else: 
     return None 


class LoginHandler(BaseHandler): 

    def get(self): 
    self.render("login.html", next=self.get_argument("next","/"), message=self.get_argument("error","")) 

    def post(self): 
    email = self.get_argument("email", "") 
    password = self.get_argument("password", "") 

    user = self.application.syncdb['users'].find_one({ 'user': email }) 

    if user and user['password'] and bcrypt.hashpw(password, user['password']) == user['password']: 
     self.set_current_user(email) 
     self.redirect("hello") 
    else: 
     error_msg = u"?error=" + tornado.escape.url_escape("Login incorrect.") 
     self.redirect(u"/login" + error_msg) 

    def set_current_user(self, user): 
    print "setting "+user 
    if user: 
     self.set_secure_cookie("user", tornado.escape.json_encode(user)) 
    else: 
     self.clear_cookie("user") 


class RegisterHandler(LoginHandler): 

    def get(self): 
    self.render( "register.html", next=self.get_argument("next","/")) 

    def post(self): 
    email = self.get_argument("email", "") 

    already_taken = self.application.syncdb['users'].find_one({ 'user': email }) 
    if already_taken: 
     error_msg = u"?error=" + tornado.escape.url_escape("Login name already taken") 
     self.redirect(u"/login" + error_msg) 


    password = self.get_argument("password", "") 
    hashed_pass = bcrypt.hashpw(password, bcrypt.gensalt(8)) 

    user = {} 
    user['user'] = email 
    user['password'] = hashed_pass 

    auth = self.application.syncdb['users'].save(user) 
    self.set_current_user(email) 

    self.redirect("hello") 
+0

嗯,感谢您指出的不明确有..在我的例子在认证方法应该在用户表中查找用户如果密码与存储的散列匹配,则返回用户。我绝对不是说要建立一个新的数据库连接,那将是疯狂的。现在为了清晰起见更新 –

+0

您的网址“我在git hub上的示例应用程序”给页面找不到错误...您能否更新此内容...? – Shiva

+0

链接已更新。 https://github.com/bootandy/tornado_sample –