为什么我的龙卷风应用程序总是重新验证?

时间:2014-02-14 14:30:01

标签: python authentication tornado

我正在构建一个基于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()

1 个答案:

答案 0 :(得分:3)

最后我找到了解决方案。调用get的{​​{1}}方法后,ProfileHandler装饰器会检查用户是否已登录。

但谁知道是否有登录用户?在基本的龙卷风功能中,这没有实现。您必须创建一个@tornado.web.authenticated和所有其他处理程序 需要此身份验证信息应该是BaseHandler

的子类

BaseHandler被定义和子类化之后 - 身份验证工作完美!

总结一下。如果您陷入登录请求的恶性循环中:

1)创建BaseHandler并覆盖BaseHandler

get_current_user

2)使用您的公共处理程序子类BaseHandler:

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)

3)添加龙卷风装饰器class ProfileHandler(BaseHandler) 以确保身份验证:

@tornado.web.authenticated