Tornado的多种验证选项

8 投票
2 回答
4535 浏览
提问于 2025-04-16 05:09

我刚开始玩Tornado,想提供多种认证方式。目前我的应用程序使用tornado.auth.GoogleMixin和Google的混合OpenID/oAuth运行得很好,未认证的用户会自动被引导到Google的认证页面。

如果一个未认证的用户想使用其他选项(比如本地认证或tornado.auth.TwitterMixin),我该如何在登录处理程序中实现选择认证方式的逻辑呢?

我在所有公开的方法上添加了装饰器'tornado.web.authenticated',这是我的登录处理类(基本上是直接来自Tornado示例),目前与Google OpenID/oAuth正常工作:

class AuthLoginHandler(BaseHandler, tornado.auth.GoogleMixin):
    @tornado.web.asynchronous
    def get(self):

        if self.get_argument('openid.mode', None):
            self.get_authenticated_user(self.async_callback(self._on_auth))
            return

        ## redirect after auth
        self.authenticate_redirect()

    def _on_auth(self, user):
        ## auth fail
        if not user:
            raise tornado.web.HTTPError(500, 'Google auth failed')

        ## auth success
        identity = self.get_argument('openid.identity', None)

        ## set identity in cookie
        self.set_secure_cookie('identity', tornado.escape.json_encode(identity))
        self.redirect('/')

感谢任何解决方案的建议。谢谢!

2 个回答

0

我自己也遇到过这个问题,不过情况稍微有点不同。

一个解决办法其实是这样做。

class AuthLoginHandler(BaseHandler, tornado.auth.GoogleMixin, tornado.auth.TwitterMixin):

    def get(self):
        if want_google:
            tornado.auth.GoogleMixin.get_authenticated_user(self)
            #...
        elif want_twitter:
            tornado.auth.TwitterMixin.get_authenticated_user(self)
        #...
11

我觉得最简单的方法就是把AuthLoginHandler改成更具体的名字,比如GoogleAuthHandler,然后为这个新名字创建一个合适的路由:

(r"/login/google/", GoogleAuthHandler),
(r"/login/facebook/", FacebookAuthHandler),

等等。

接着在页面上简单地创建每个认证提供商的链接,比如:

<a href="/login/google/>Login with Google</a>
<a href="/login/facebook/">Login with Facebook</a>

如果你想让它看起来更高级一点,可以把这些提供商放在一个下拉框里,或者如果你真的想做得很炫,可以解析他们的'openid'网址(比如,如果是username.google.com,就可以用self.redirect("/login/google")),但这假设用户知道他们的OpenID提供商网址,而这通常不是情况。我觉得如果给他们提供一个谷歌、脸书或推特的图标让他们点击,可能会让大多数人更容易理解。

撰写回答