2011-06-29 14 views
18

Me preguntaba si alguien sabe de algún código de ejemplo o tutoriales sobre la implementación de una página de inicio de sesión en Tornado. He visto los ejemplos que vienen con eso, pero parecen muy facebook/oauth céntrico.Tornado login Ejemplos/Tutoriales

Respuesta

31

Aquí hay un controlador de ejemplo simple, que necesita una plantilla login.html que contiene un formulario de nombre de usuario/contraseña. No tengo un ejemplo de registro, pero es bastante similar, en la publicación valida la entrada e inserta el registro del usuario en lugar de autenticarlo.

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

que empecé a usar el ejemplo de Cole, pero se dio cuenta de que estaba creando una cuenta para acceder a la base de datos que podría no ser lo mismo que una cuenta para nuestra aplicación web.

He cambiado el ejemplo anterior para usar bcrpyt. Ahora la conexión de un usuario a nuestra aplicación web es diferente de la conexión de nuestra aplicación web a la base de datos. My sample app on github

Nota: bcrpyt es computacionalmente pesado y bloqueará el bucle 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

hmm, gracias por señalar la falta de claridad allí .. Se supone que el método de autenticar en mi ejemplo para buscar un usuario en la tabla de usuarios y devuelve un usuario si la contraseña coincide con el hash almacenado. Definitivamente no significaba establecer una nueva conexión a la base de datos, sería una locura. Actualizado ahora para mayor claridad. –

+0

Tu url "mi aplicación de muestra en git hub" dando error de página no encontrada ... ¿Puedes actualizar esto por favor ...? – Shiva

+0

enlace actualizado. https://github.com/bootandy/tornado_sample –