首页 > 解决方案 > 如何将用户引导到登录页面而不是 Flask HTTPBasicAuth 中的登录弹出窗口?

问题描述

使用 HTTPBasicAuth 重定向到登录页面的正确方法是什么?到目前为止,它总是将我带到该verify_password功能,并且显示一个弹出窗口,要求输入用户名和密码。相反,我希望它重定向到登录页面,然后记住用户已通过该登录页面成功进行身份验证。HTTPBasicAuth 官方页面没有解释。

在此处输入图像描述

这是我当前的代码:

#!flask/bin/python
from flask import Flask, jsonify, abort, request, make_response, url_for
from flask import render_template
from flask_httpauth import HTTPBasicAuth

#Attribution: https://blog.miguelgrinberg.com/post/designing-a-restful-api-with-python-and-flask
#reference: https://github.com/realpython/discover-flask
#Needs: pip install flask-httpauth

app = Flask(__name__)
auth = HTTPBasicAuth()

@app.route('/', methods=['GET','POST'])
@auth.login_required
def login():
    print('in login')
    print(request.values.get('email'), request.values.get('password'))
    templateToReturn = 'login.html'
    if request.method == 'POST':
        print('in post')
        username = request.values.get('email')
        password = request.values.get('password')
        if verify_password(username, password):
            print('password verified')
            templateToReturn = 'index.html'
    print('Curr user', auth.current_user())
    print('request: ', request.method)
    if request.method == 'GET' and auth.current_user():
        templateToReturn = 'index.html'
    return render_template(templateToReturn)

@auth.verify_password
def verify_password(email, password):
    print('in verify pwd')
    return verifyAuthentication(email, password)

def verifyAuthentication(email, password):
    knownUsers = {'p1@gmail.com': 'pass', 
                  'p2@yahoo.com': 'pass'}
    authenticated = False
    if email in knownUsers:
        if knownUsers[email] == password:
            authenticated = True
    return authenticated

@app.route('/logout')
def logout():
    return render_template('logout.html')

@auth.error_handler
def unauthorized():
    return '<!DOCTYPE html><html><body><div style="text-align: center;">Unauthorized access</div></body></html>'
    
@app.errorhandler(400)
def bad_request(error):
    return '<!DOCTYPE html><html><body><div style="text-align: center;">Bad request</div></body></html>'

@app.errorhandler(404)
def not_found(error):
    return '<!DOCTYPE html><html><body><div style="text-align: center;">Page not found</div></body></html>'

if __name__ == '__main__':
    app.run(debug=True, host="0.0.0.0")

和登录表单login.html

<form action="{{ url_for('/') }}" method="POST">
      <div class="row">
        <div class="input-field col s12">
          <input id="email" name="email" type="email" class="validate">
          <label for="email">Email</label>
        </div>
      </div>

      <div class="row">
        <div class="input-field col s12">
          <input id="password" name="password" type="password" class="validate">
          <label for="password">Password</label>
        </div>
      </div>

      <button type="submit" id="login" class="waves-effect waves-light btn blue darken-1" style="width:100%;">Login</button>
    <br>
</form>

标签: authenticationflaskforms-authenticationhttp-authentication

解决方案


根据HTTPBasicAuth作者的回复:

该库实现了一些来自 HTTP 标准的算法,最重要的是 HTTP 基本身份验证协议。这不是创建登录表单的库,通常您甚至不会使用登录表单。

如果您想为使用 HTML 的应用程序创建登录体验,我建议您查看 Flask-Login 扩展,它更适合您的用例。


推荐阅读