Я только учусь программировать, и это сводит меня с ума. Я не знаю, упускаю ли я что-то очень простое или совершенно не понимаю, как работает аутентификация (вполне возможно, и то, и другое), однако я был бы признателен за помощь.
Я создал маршрут входа в систему для своего флеш-приложения, которое отображает следующее и успешно позволяет пользователю войти в систему.
Если пользователь успешно входит в систему, я хочу установить заголовок авторизации, используя токен, созданный с помощью JWT. Я использую библиотеку запросов для этого и получаю ответ 200, но каждый раз, когда я проверяю вкладку сети, я не вижу токен в заголовке ответа «Авторизация».
Идея состоит в том, что после того, как этот заголовок установлен, я могу защитить свой apis, убедившись, что токен присутствует, а также использовать эту информацию, чтобы гарантировать, что API-интерфейсы возвращают данные только для этого пользователя, то есть расшифровывают токен для работы с пользователем.
Вкладка «Сеть» — без заголовка авторизации
Это мой текущий код. Где я ошибаюсь? Правильно ли звучит мой подход?
@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 = 'https://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')
Несколько вещей, которые здесь сбивают с толку:
В методе
login()
вы делаетеrequests.get()
вызов. Похоже, вы вызываете новую конечную точку из своего приложения. Так оно и должно работать? Если быть точным, похоже, вы проверяете учетные данные пользователя, запускаете JWT, а затем вызываете/login
конечную точку приложения, прослушивающего порт5000
, устанавливая JWT в качестве токена-носителя.Authorization
— заголовок запроса. Вы не используете его в ответах клиенту. Если вы хотите вернуть JWT клиенту, используйте один из потоков OAuth, либо Поток кода (предпочтительно) или неявный поток.Как только вы передадите токен своему клиенту, вы должны использовать его, как вы сказали — установить в заголовке
Authorization
как токенBearer
. Поскольку вы используете Flask, вы можете использовать этот фильтр для защиты своих API.