2011-06-29 23 views
18

Zastanawiam się, czy ktoś wie o jakimś przykładowym kodzie lub samouczkach dotyczących implementacji strony logowania/rejestracji w Tornado? Widziałem przykłady, które się z tym wiążą, ale wydają się bardzo skoncentrowane na facebookach/oauth.Tornado zaloguj się Przykłady/Poradniki

Odpowiedz

31

Oto prosty przykładowy program obsługi, który wymaga szablonu login.html zawierającego formularz nazwa użytkownika/hasło. Nie mam przykładu rejestracji, ale jest to bardzo podobne, w poście sprawdzasz poprawność danych wejściowych i wstawiasz rekord użytkownika zamiast uwierzytelniania.

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

zacząłem używać przykład Cole'a, ale uświadomiłem sobie, że utworzenie konta dla dostępu do bazy danych, która może nie być tak samo jak konta dla naszego webapp.

Zmieniłem powyższy przykład, aby używać bcrpyt. Teraz połączenie użytkownika z naszą aplikacją webową różni się od połączenia naszej przeglądarki z bazą danych. My sample app on github

Uwaga: bcrpyt jest obliczeniowo ciężkie i zablokuje pętli 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, dzięki za wskazanie istnieją niejasności .. metoda uwierzytelnienia w moim przykładzie ma odnośnika użytkownika w tabeli użytkowników i zwróć użytkownika, jeśli hasło pasuje do przechowywanego skrótu. Zdecydowanie nie miałem na myśli ustanowienia nowego połączenia z bazą danych, to byłoby szalone. Zaktualizowany teraz dla jasności. –

+0

Twój adres URL "moja przykładowa aplikacja na git hub" podając błąd nie znaleziono strony ... Czy możesz zaktualizować to proszę ...? Zaktualizowano link: – Shiva

+0

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