4

我正在尝试让bottle.py 与repoze.who 一起工作,到目前为止,我已经设法组合了以下非常简单的程序来使其工作,并结合了我找到的各种示例。显然这不是我在生产中运行的东西,我只是想尽可能地制作最简单的代码,以便我可以学习如何使用它 - 但不幸的是,使用 bottle.py 和 repoze.who 的教程是很少而且相差甚远。

下面的示例有效,并允许某人使用 admin/admin 的用户名/密码登录。我应该如何处理 repoze.who 以使 logout() 函数工作?我收集了一个可能用于此目的的忘记功能,但我无法弄清楚我应该如何调用它。

谢谢。

from bottle import route, run, app, get, abort, request

from StringIO import StringIO
import repoze
from repoze.who.middleware import PluggableAuthenticationMiddleware
from repoze.who.interfaces import IIdentifier
from repoze.who.interfaces import IChallenger
from repoze.who.plugins.basicauth import BasicAuthPlugin
from repoze.who.plugins.auth_tkt import AuthTktCookiePlugin
from repoze.who.plugins.cookie import InsecureCookiePlugin
from repoze.who.plugins.form import FormPlugin
from repoze.who.plugins.htpasswd import HTPasswdPlugin
from repoze.who.classifiers import default_request_classifier
from repoze.who.classifiers import default_challenge_decider    

import logging, sys
import pprint

@route('/')
def root():
    if request.environ.get('repoze.who.identity') is None:
        abort(401, "Not authenticated")
    return "Authenticated"


@route('/hello')
def index():
    identity = request.environ.get('repoze.who.identity')
    if identity == None:
        abort(401, "Not authenticated")

    user = identity.get('repoze.who.userid')
    return '<b>Hello %s!</b>' % user

@route('/logout')
def logout():
    # I have no idea what to put here
    pass

io = StringIO()
salt = 'aa'

for name, password in [ ('admin', 'admin'), ('paul', 'paul') ]:
    io.write('%s:%s\n' % (name, password))
io.seek(0)

def cleartext_check(password, hashed):
    return password == hashed

htpasswd = HTPasswdPlugin(io, cleartext_check)
basicauth = BasicAuthPlugin('repoze.who')
auth_tkt = AuthTktCookiePlugin('secret', 'auth_tkt')
form = FormPlugin('__do_login', rememberer_name='auth_tkt')
form.classifications = { IIdentifier:['browser'],
                         IChallenger:['browser'] }
identifiers = [('form', form),('auth_tkt',auth_tkt),('basicauth',basicauth)]
authenticators = [('htpasswd', htpasswd)]
challengers = [('form',form), ('basicauth',basicauth)]
mdproviders = []


log_stream = None
import os
if os.environ.get('WHO_LOG'):
    log_stream = sys.stdout

middleware = PluggableAuthenticationMiddleware(
    app(),
    identifiers,
    authenticators,
    challengers,
    mdproviders,
    default_request_classifier,
    default_challenge_decider,

    log_stream = log_stream,
    log_level = logging.DEBUG
    )

if __name__ == '__main__':
    run(app=middleware, host='0.0.0.0', port=8080, reloader=True)
else:
    application = middleware

run(host='0.0.0.0', port=8080)
4

2 回答 2

2

如果可以的话,我会使用RedirectingFormPlugin而不是FormPlugin. RedirectingFormPlugin允许您注册注销 URL。有了它,您不必为您实现/logout处理程序,例如RedirectingFormPlugin拦截请求并处理忘记的调用等。我已经将它与 Bobo 和 appengine 一起使用,并且效果很好。

于 2012-07-12T12:26:18.023 回答
0

如果您仍然想在旧的 repoze.who v1 中以不受欢迎的方式进行操作,以下对我有用:

from bottle import response # , redirect
# ...
@route('/logout')
def logout():
    identity = request.environ.get('repoze.who.identity')
    if identity:
        for (i_name, i) in identifiers:
            hdrs = i.forget(request.environ, identity)
            [ response.add_header(*h) for h in hdrs ]
    ## following would be nice, but does not work,
    ## since redirect is not using defined response headers
    # rfr = request.get_header('referer', '/')
    # redirect(rfr)
    ## so we do just this:
    return "you have been hopefully logged out"
于 2013-08-27T15:52:26.170 回答