添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
By using our site, you acknowledge that you have read and understand our Cookie Policy , Privacy Policy , and our Terms of Service .

I was wondering if anyone know of any example code or tutorials on implementing a login/signup page in Tornado? Ive seen the examples that come with it, but they seem very facebook/oauth centric.

closed as off-topic by hopper , Jamie Hutber , Rushyo , manouti , AndyG Oct 1 '14 at 18:05

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions asking us to recommend or find a book, tool, software library, tutorial or other off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it." – hopper, Jamie Hutber, Rushyo, manouti, AndyG
If this question can be reworded to fit the rules in the help center , please edit the question .

Here's a simple example handler, which needs a login.html template containing a username/password form. I don't have a sign up example, but it's quite similar, on the post you validate the input and insert the user record rather than authenticating.

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)

I started using Cole's example but realised I was creating an account for accessing the database which might not be the same thing as an account for our webapp.

I've changed the above example to use bcrpyt. Now a user's connection to our webapp is different from our webapp's connection to the database. My sample app on github

Note: bcrpyt is computationally heavy and will block the IO loop

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")
                hmm, thanks for pointing out the unclearness there.. the authenticate method in my example is supposed to lookup a user in the users table, and return a user if the password matches the stored hash. I definitely did not mean establish a new database connection, that would be insane. Updated now for clarity.
                    – Cole Maclean
                May 18 '12 at 17:50
                Your url "my sample app on git hub" giving page not found error...Can you update this please...?
                    – Shiva
                Apr 25 '14 at 5:49