2014-02-14 82 views
0

我正在構建一個基於Python龍捲風的Web應用程序,我正在努力應對身份驗證過程。根據龍捲風提供的演示,我通過Google創建一個身份驗證。爲什麼我的龍捲風應用程序總是重新驗證?

  • 我驗證並重定向到我的索引。
  • 我嘗試連接到我的/profile網站,但龍捲風將我重定向到Google身份驗證和我的索引。

/profile要求用戶通過身份驗證。在我的情況下,龍捲風似乎並沒有 接受它或我在認證類中犯了一個錯誤。

爲什麼我無法訪問我的/profile網站?我在做什麼錯誤的身份驗證?

認證相關的處理程序

from site import models 

import mongoengine 

import tornado.auth 
import tornado.escape 
import tornado.ioloop 
import tornado.web 

from tornado import gen 

class BaseHandler(tornado.web.RequestHandler): 

    def get_current_user(self): 

     user_json = self.get_secure_cookie("mysite") 
     if not user_json: return None 
     return tornado.escape.json_decode(user_json) 


class AuthGoogleLoginHandler(BaseHandler, tornado.auth.GoogleMixin): 

    @gen.coroutine 
    def get(self): 

     if self.get_argument("openid.mode", None): 
      user = yield self.get_authenticated_user() 
      self.set_secure_cookie("mysite", 
            tornado.escape.json_encode(user)) 

      email = user.get('email') 

      try: 
       print 'trying to find the user' 
       usr = models.User.objects.get(email=email) 

      except mongoengine.DoesNotExist as e: 

       # there is no user with the wished email address 
       # let's create a new one. 
       new_user = models.User() 
       new_user.email = user.get('email') 
       new_user.first_name = user.get('first_name') 
       new_user.last_name = user.get('last_name') 
       new_user.locale = user.get('locale') 

       new_user.save() 

      self.redirect('/') 
      return 

     self.authenticate_redirect() 


class AuthLogoutHandler(BaseHandler): 
    ''' 
    Log the current user out. 
    ''' 

    def get(self): 
     self.clear_cookie("mysite") 
     self.redirect('/') 

其他處理器和主

from mysite import models 

from mysite import auth 

from tornado.options import options, define, parse_command_line 
import django.core.handlers.wsgi 
import tornado.httpserver 
import tornado.ioloop 
import tornado.web 
import tornado.escape 
import tornado.wsgi 
import os 

define('port', type=int, default=1234) 

class ProfileHandler(tornado.web.RequestHandler): 

    @tornado.web.authenticated 
    def get(self): 

     join = lambda x, y, separator: separator.join([x, y]) 
     self.render('profile.html', user=user, join=join) 


class ProfileEditHandler(tornado.web.RequestHandler): 

    @tornado.web.authenticated 
    def get(self):  
     self.render('profile-edit.html', user=user) 

    @tornado.web.authenticated 
    def post(self): 

     first_name = self.get_argument('first_name') 
     last_name = self.get_argument('last_name') 

     city = self.get_argument('city') 
     state = self.get_argument('state') 
     country = self.get_argument('country') 

     # write to MongoDB 
     self.redirect('/profile') 

class IndexHandler(tornado.web.RequestHandler): 
    def get(self): 
     self.render('welcome.html')  

def main(): 

    template_path=os.path.join(os.path.abspath(os.path.dirname(__file__)),"templates") 
    static_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'static') 

    wsgi_app = tornado.wsgi.WSGIContainer(django.core.handlers.wsgi.WSGIHandler()) 

    handlers = [('/profile', ProfileHandler), 
       ('/profile-edit', ProfileEditHandler), 
       ('/auth/login', auth.AuthGoogleLoginHandler), 
       ('/auth/logout', auth.AuthLogoutHandler), 
       ('/', IndexHandler), 
       ('.*', tornado.web.FallbackHandler, dict(fallback=wsgi_app)),] 

    tornado_app = tornado.web.Application(handlers, 
              static_path=static_path, 
              template_path=template_path, 
              cookie_secret='some_secret', 
              login_url='/auth/login', 
              debug=True) 

    server = tornado.httpserver.HTTPServer(tornado_app) 
    server.listen(options.port) 
    tornado.ioloop.IOLoop.instance().start() 

if __name__ == '__main__': 
    main() 

回答

2

最後,我找到了解決辦法。當我的ProfileHandlerget方法被稱爲@tornado.web.authenticated裝飾器檢查用戶是否登錄。

但是誰發現是否有登錄用戶?在基本的龍捲風功能中沒有實現。你必須創建一個BaseHandler和 需要此認證信息的所有其他處理程序應劃分爲BaseHandler的子類。

BaseHandler被定義和子類別化後 - 認證工作完美!

總結一下。如果您陷入登錄請求的惡性循環:

1)創建一個BaseHandler並覆蓋get_current_user

class BaseHandler(tornado.web.RequestHandler): 
    def get_current_user(self): 

     user_json = self.get_secure_cookie("heroe") 
     if not user_json: return None 
     return tornado.escape.json_decode(user_json) 

2)子類BaseHandler與您共同處理程序:

class ProfileHandler(BaseHandler) 

3)添加龍捲風裝飾@tornado.web.authenticated確保認證:

class ProfileHandler(auth.BaseHandler): 

    @tornado.web.authenticated 
    def get(self): 
     self.render('profile.html')