【问题标题】:How to send a password to a Flask app when using Docker/Kubernetes?使用 Docker/Kubernetes 时如何向 Flask 应用程序发送密码?
【发布时间】:2021-11-07 12:38:09
【问题描述】:

背景:
我知道这是一个非常基本的问题,但我没有前端应用程序的经验。我最近尝试将GET 请求从静态 HTML 页面发送到在云服务器上的 Docker 中运行的应用程序,但它没有工作。所以现在我正在尝试一个进行身份验证的 Flask 应用,而不是 HTML 页面。

我想做的事:
创建一个索引页面,如果用户登录,他们会看到一些产品。如果用户未登录,他们会看到一个登录表单以输入他们的电子邮件 ID 和密码。
Flask 应用程序将部署在 Docker 中,并可通过 Kubernetes Ingress 在 Kubernetes 云集群上使用。 我主要担心的是用户名和密码如何从客户端浏览器找到正确的服务。它是通过在 HTML 页面本身生成的POST 完成的吗? POST 请求不是必须指向某个特定的URL 吗?单击Login 按钮时,是否应该通过某些JQuery 脚本对密码进行哈希处理?

我无法弄清楚:
即使在看到lot of examples 之后,当用户键入他们的电子邮件和密码并单击“登录”按钮时,我也无法找出正确的方法来散列并向 Flash 应用程序发送密码。然后,如果用户已登录,它必须呈现一个显示产品的 HTML 页面。

如果有一种无需flask-httpauth(使用pip install flask-httpauth 安装)的简单方法,或者如果有一个语法更简洁的库,那么也欢迎使用该技术。

烧瓶代码:

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

app = Flask(__name__, static_url_path = "")
auth = HTTPBasicAuth()

@app.route('/')
@auth.login_required
def welcome():
    return render_template('index.html')

@app.route('/logout')
def welcome():
    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 not_found(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")

登录页面:index.html

   <!DOCTYPE html>
  <html>
    <head>
      <meta charset="UTF-8" />
      <title>Vacation Finder</title>
      <!--Import materialize.css-->
      <link type="text/css" rel="stylesheet" href="materialize.min.css"/>
      <!--Let browser know website is optimized for mobile-->
      <meta name="viewport" content="width=device-width, initial-scale=1.0"/>          
    </head>

    <body>
        <div>
          <nav>
            <div class="nav-wrapper grey darken-4">
              <div style="text-align: center; font-size: 30px; font-weight: bold;">Some page</div>
                <div class="row">
                    <div class="col s12 m8 l4 offset-m2 offset-l4">
                        <br>
                        <br>
                        <div class="card">
                            
                            <div class="card-content">
                            
                                  <div class="row">
                                    <div class="input-field col s12">
                                      <input id="email" type="email" class="validate">
                                      <label for="email">Email</label>
                                    </div>
                                  </div>

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

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

                        </div>
                    </div>
                </div>
            </div>
          </nav>
        </div>
  
    </body>
  </html> 

【问题讨论】:

    标签: python docker flask kubernetes


    【解决方案1】:

    您可以根据需要使用 JWT 令牌

    https://geekflare.com/securing-flask-api-with-jwt/

    @app.route('/login', methods=['GET', 'POST'])  
    def login_user(): 
     
      auth = request.authorization   
    
      if not auth or not auth.username or not auth.password:  
         return make_response('could not verify', 401, {'WWW.Authentication': 'Basic realm: "login required"'})    
    
      user = Users.query.filter_by(name=auth.username).first()   
         
      if check_password_hash(user.password, auth.password):  
         token = jwt.encode({'public_id': user.public_id, 'exp' : datetime.datetime.utcnow() + datetime.timedelta(minutes=30)}, app.config['SECRET_KEY'])  
         return jsonify({'token' : token.decode('UTF-8')}) 
    
      return make_response('could not verify',  401, {'WWW.Authentication': 'Basic realm: "login required"'})
    

    除此之外,您还可以查看官方 bookinfo 应用程序 istio 示例:您还可以查看此示例:https://github.com/istio/istio/tree/master/samples/bookinfo/src/productpage

    智威汤逊:https://medium.com/@apcelent/json-web-token-tutorial-with-example-in-python-df7dda73b579

    https://fastapi.tiangolo.com/tutorial/security/oauth2-jwt/

    https://realpython.com/token-based-authentication-with-flask/

    【讨论】:

    • 谢谢你苛刻。这些链接很有用,但我遇到的主要问题是将用户名和密码发送到 Flask 应用程序。
    • 如果前端处理东西,您可以通过服务名称将其发送到后端服务。前端将在 k8s 内部通过 svc 名称向后端服务发送数据
    • 这是我在第一段中提到的。当我尝试使用 JQuery GET 发送它时,它没有被发送。见stackoverflow.com/questions/68820608/…。我能得到的最好的帮助是通过添加到我现有代码中的一些代码。我现在意识到我应该为登录页面使用表单,但我仍然不明白密码将如何被散列和发送。
    猜你喜欢
    • 2018-12-03
    • 2021-05-04
    • 2019-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 1970-01-01
    相关资源
    最近更新 更多