Header 中没有访问令牌,即使在指定之后也是如此:Flask 和 JWT

No Access Token in Header Even After Specifying It : Flask & JWT

我已经使用 flask、sqlite3、sqlalchemy 和 JWT 创建了一个基本应用程序来进行用户身份验证。我的装饰器如下[请原谅格式我向你保证代码中的缩进是正确的]:

def token_required(f):
  @wraps(f)
  def decorated(*args, **kwargs):
    token = None
    print(request.headers)
    if 'x_access_token' in request.headers:
        token = request.headers['X-Access-Token']

    if not token:
        return jsonify({'message' : 'Token is missing.'}), 401

    try:
        data = jwt.decode(token, SECRET_KEY)
        current_user = User.query.filter_by(public_id=data['public_id']).first()
    except:
        return jsonify({'message': 'Token is invalid.'}), 401

    return f(current_user, *args, **kwargs)
return decorated

我的主要登录路线是我要求输入用户名和密码的地方,如果可行,我将 header 中的 jwt 令牌传递到需要令牌的路线:

@Main.route('/login', methods=['GET', 'POST'])
def login():
auth = request.authorization

if not auth or not auth.username or not auth.password:
    return make_response('Could not verify!', 401, {'WWW-Authenticate' : 'Basic realm="Login Required!"'})

user = User.query.filter_by(username=auth.username).first()

if not user:
    return make_response('Could not verify!', 401, {'WWW-Authenticate': 'Basic realm="Incorrect username"'})

if check_password_hash(user.password, auth.password):
    token = jwt.encode({'public_id' : user.public_id,
                        'exp' : datetime.datetime.utcnow() + datetime.timedelta(seconds=5000)},
                        SECRET_KEY)
    response = redirect(url_for('Main.views'))
    response.headers['X-Access-Token'] = token.decode('UTF-8')
    print('hi', response.headers)
    return response
    # return response_builder('Main.views', token)
else:
    return make_response('Could not verify!', 401, {'WWW-Authenticate': 'Basic realm="Incorrect password"'})

但是当我的名为 views 的路由打开时,它无法在 header 中找到令牌,导致我的装饰器的其他部分被执行,即缺少令牌。

我打印了我在 /login:

回复中发送的 headers
Content-Type: text/html; charset=utf-8
Content-Length: 219
Location: /views
X-Access-Token: [a long hashed value]

当我在装饰器中打印 headers 时,我认为登录重定向到没有 x-access-token!

Host: localhost:5000
Connection: keep-alive
Cache-Control: max-age=0
Authorization: Basic YWJoaTphYmhp
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/537.36 (KHTML, like 
Gecko) Chrome/83.0.4103.61 Safari/537.36
Accept: 
text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;
q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: Pycharm-6d7a12e6=5d65ff91-afab-45ec-8de8-a23e44c046dd; __test=1; username-localhost- 
8888="2|1:0|10:1590510962|23:username-localhost- 
8888|44:MTA2YjkyMWJiMmU2NDU1MGFmM2Q5MjZhZGE5YjEwODA=|
f3ea838f5405f6c102ddbaf45dfef9bd000d2d183eaba9310d698d1005a6c21b"; 
session=eyJkYl9uYW1lIjoibXlfaGlzdCJ9.Xt-9aA.vDjCIXn731CioU72zCiJFim1shg

这是我的观点,需要令牌:

 # views page for navigation
    @Main.route('/views')
    @token_required
    def views(current_user):
        print(current_user)
        return render_template('Main/Views.html')

我尝试的另一种方法而不是重定向是 make_response 并且该方法也有效,它似乎只是跳过装饰器并在页面上呈现/视图。不是 /views 的 html,而是字面上的 /views

您混合使用下划线和连字符。

尝试改变

if 'x_access_token' in request.headers:
    token = request.headers['X-Access-Token']

寻找'x-access-token'

Headers,除了简单的,中间不能设置。

no-cors — 防止方法是 HEAD、GET 或 POST 以外的任何方法,并且 headers 不是简单 headers 以外的任何方法。如果任何 ServiceWorker 拦截这些请求,它们可能不会添加或覆盖任何 headers,除了那些简单的 headers。此外,JavaScript 可能无法访问结果响应的任何属性。这确保了 ServiceWorkers 不会影响 Web 的语义,并防止因跨域泄漏数据而引起的安全和隐私问题。