设置授权标头 - 使用 Python 请求和 JWT 的 Flask 应用程序

Posted

技术标签:

【中文标题】设置授权标头 - 使用 Python 请求和 JWT 的 Flask 应用程序【英文标题】:Setting Authorization header - Flask app using Python Requests and JWT 【发布时间】:2021-06-26 21:31:30 【问题描述】:

我只是在学习编码,这让我发疯了。我不知道我是否遗漏了一些非常简单的东西,或者完全误解了身份验证的工作原理(很可能两者兼而有之),但是,我希望有人能提供帮助。

我为我的烧瓶应用程序创建了一个登录路由,它呈现以下内容并成功允许用户登录。

Login Page

如果用户成功登录,我想使用使用 JWT 生成的令牌设置授权标头。我正在使用请求库来执行此操作并获得 200 响应,但每次我检查网络选项卡时,我都无法在“授权”响应标头中看到令牌。

这个想法是,一旦设置了此标头,我可以通过确保存在令牌来保护我的 API,并使用该信息来确保 API 仅返回该用户的数据,即解密令牌以计算出用户。

Network tab - No Authorization Header

这是我当前的代码。我哪里错了?我的方法听起来正确吗?

@loginsBlueprint.route('/login', methods=['GET', 'POST'])
def login():
    error = None
    if request.method == 'POST':
        user = User.query.filter_by(username=request.form['username']).first()
        if user is not None and bcrypt.check_password_hash(user.password, request.form['password']):
            token = jwt.encode(
                'user': request.form['username'], 'exp': datetime.datetime.utcnow() + datetime.timedelta(seconds=15),
                app.config['SECRET_KEY'])

            url = 'http://127.0.0.1:5000/login'
            headers = 'Authorization': 'Bearer ' + token
            requests.get(url, headers=headers)

            return render_template('landing_page.html')
        else:
            return make_response('Could not verify', 403,
                                 'WWW-Authenticate': 'Basic realm ="Wrong Password !!"')
    return render_template('login.html', error=error)

login.html

<html>
  <head>
    <title>Flask Intro - login page</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="static/bootstrap.min.css" rel="stylesheet" media="screen">
  </head>
  <body>
    <div class="container">
      <h1>Please login</h1>
      <br>
      <form action="" method="post">
        <input type="text" placeholder="Username" name="username" value="
          request.form.username ">
         <input type="password" placeholder="Password" name="password" value="
          request.form.password ">
        <input class="btn btn-default" type="submit" value="Login">
      </form>
      % if error %
        <p class="error"><strong>Error:</strong>  error 
      % endif %
    </div>
  </body>
</html>

注意:我已尝试更改为 requests.post,但得到了 400:

127.0.0.1 - - [30/Mar/2021 21:53:29] "←[31m←[1mPOST /login HTTP/1.1←[0m" 400 

我认为这可能是因为我正在使用 CORS,所以将其添加到:

CORS(app, expose_headers='Authorization')

【问题讨论】:

【参考方案1】:

这里有一些令人困惑的事情:

    login() 方法中,您进行requests.get() 调用。所以看起来你正在从你的应用程序调用一个新的端点。它应该是这样工作的吗?确切地说,您似乎检查了用户的凭据,发出 JWT,然后调用侦听端口 5000 的应用程序的 /login 端点,将 JWT 设置为不记名令牌。

    Authorization 是一个请求头。您不会在响应客户时使用它。如果您想将 JWT 返回给客户端,请使用其中一种 OAuth 流程,Code flow(最好)或Implicit flow。

    一旦您将令牌发送给您的客户,那么您应该按照您所说的使用它 - 在 Authorization 标头中设置为 Bearer 令牌。当您使用烧瓶时,您可以使用this filter 来保护您的 API。

【讨论】:

以上是关于设置授权标头 - 使用 Python 请求和 JWT 的 Flask 应用程序的主要内容,如果未能解决你的问题,请参考以下文章

Swift:未设置请求授权标头

重定向的瓶子设置授权标头

如何设置授权标头(JWT)

如何在 Android OKHTTPClient 请求上设置(OAuth 令牌)授权标头

如何在 Android OKHTTPClient 请求上设置(OAuth 令牌)授权标头

无法设置 URLRequest 授权标头