赞
踩
flask身份验证
This tutorial takes a test-first approach to implementing token-based authentication in a Flask app using JSON Web Tokens (JWTs).
本教程采用测试优先的方法,使用JSON Web令牌(JWT)在Flask应用中实现基于令牌的身份验证。
Updates:
更新:
By the end of this tutorial, you will be able to…
在本教程结束时,您将能够...
Free Bonus: Click here to get access to a free Flask + Python video tutorial that shows you how to build Flask web app, step-by-step.
免费红利: 单击此处可访问免费的Flask + Python视频教程 ,该教程逐步向您展示如何构建Flask Web应用程序。
JSON Web Tokens (or JWTs) provide a means of transmitting information from the client to the server in a stateless, secure way.
JSON Web令牌 (或JWT)提供了一种以无状态 ,安全的方式将信息从客户端传输到服务器的方法。
On the server, JWTs are generated by signing user information via a secret key, which are then securely stored on the client. This form of auth works well with modern, single page applications. For more on this, along with the pros and cons of using JWTs vs. session and cookie-based auth, please review the following articles:
在服务器上,通过秘密密钥对用户信息签名来生成JWT,然后将JWT安全地存储在客户端上。 这种形式的身份验证可与现代的单页应用程序很好地配合使用。 有关此的更多信息,以及使用JWT与会话和基于Cookie的身份验证的优缺点,请查看以下文章:
NOTE: Keep in mind that since a JWT is signed rather than encrypted it should never contain sensitive information like a user’s password.
注意:请记住,由于JWT是经过签名而不是加密的,因此它绝不应包含敏感信息,例如用户密码。
Enough theory, let’s start implementing some code!
理论足够多,让我们开始实现一些代码!
Start by cloning the project boilerplate and then create a new branch:
首先克隆项目样板,然后创建一个新分支:
- $ git clone https://github.com/realpython/flask-jwt-auth.git
- $ git clone https://github.com/realpython/flask-jwt-auth.git
- $ $ cd flask-jwt-auth
- cd flask-jwt-auth
- $ git checkout tags/1.0.0 -b jwt-auth
- $ git checkout tags/1.0.0 -b jwt-auth
Create and activate a virtualenv and install the dependencies:
创建并激活virtualenv并安装依赖项:
This is optional, but it’s a good idea to create a new Github repository and update the remote:
这是可选的,但是最好创建一个新的Github存储库并更新远程服务器:
- (env)$ git remote set-url origin <newurl>
- (env)$ git remote set-url origin <newurl>
Let’s set up Postgres.
让我们设置Postgres。
NOTE: If you’re on a Mac, check out Postgres app.
注意 :如果您使用的是Mac,请查看Postgres应用 。
Once the local Postgres server is running, create two new databases from psql
that share the same name as your project name:
一旦本地Postgres服务器运行,从psql
创建两个新数据库,它们共享与您的项目名称相同的名称:
NOTE: There may be some variation on the above commands, for creating a database, based upon your version of Postgres. Check for the correct command in the Postgres documentation.
注意 :根据您使用的Postgres版本,上述命令在创建数据库时可能会有一些变化。 在Postgres文档中检查正确的命令。
Before applying the database migrations we need to update the config file found in project/server/config.py. Simply update the database_name
:
在应用数据库迁移之前,我们需要更新位于project / server / config.py中的配置文件。 只需更新database_name
:
- database_name database_name = = 'flask_jwt_auth'
- 'flask_jwt_auth'
Set the environment variables in the terminal:
在终端中设置环境变量:
Update the following tests in project/tests/test__config.py:
在project / tests / test__config.py中更新以下测试:
- class class TestDevelopmentConfigTestDevelopmentConfig (( TestCaseTestCase ):
- ):
- def def create_appcreate_app (( selfself ):
- ):
- appapp .. configconfig .. from_objectfrom_object (( 'project.server.config.DevelopmentConfig''project.server.config.DevelopmentConfig' )
- )
- return return app
-
- app
-
- def def test_app_is_developmenttest_app_is_development (( selfself ):
- ):
- selfself .. assertTrueassertTrue (( appapp .. configconfig [[ 'DEBUG''DEBUG' ] ] is is TrueTrue )
- )
- selfself .. assertFalseassertFalse (( current_app current_app is is NoneNone )
- )
- selfself .. assertTrueassertTrue (
- (
- appapp .. configconfig [[ 'SQLALCHEMY_DATABASE_URI''SQLALCHEMY_DATABASE_URI' ] ] == == 'postgresql://postgres:@localhost/flask_jwt_auth'
- 'postgresql://postgres:@localhost/flask_jwt_auth'
- )
-
-
- )
-
-
- class class TestTestingConfigTestTestingConfig (( TestCaseTestCase ):
- ):
- def def create_appcreate_app (( selfself ):
- ):
- appapp .. configconfig .. from_objectfrom_object (( 'project.server.config.TestingConfig''project.server.config.TestingConfig' )
- )
- return return app
-
- app
-
- def def test_app_is_testingtest_app_is_testing (( selfself ):
- ):
- selfself .. assertTrueassertTrue (( appapp .. configconfig [[ 'DEBUG''DEBUG' ])
- ])
- selfself .. assertTrueassertTrue (
- (
- appapp .. configconfig [[ 'SQLALCHEMY_DATABASE_URI''SQLALCHEMY_DATABASE_URI' ] ] == == 'postgresql://postgres:@localhost/flask_jwt_auth_test'
- 'postgresql://postgres:@localhost/flask_jwt_auth_test'
- )
- )
Run them to ensure they still pass:
运行它们以确保它们仍然通过:
You should see:
您应该看到:
- test_app_is_development (test__config.TestDevelopmentConfig) ... ok
- test_app_is_development (test__config.TestDevelopmentConfig) ... ok
- test_app_is_production (test__config.TestProductionConfig) ... ok
- test_app_is_production (test__config.TestProductionConfig) ... ok
- test_app_is_testing (test__config.TestTestingConfig) ... ok
-
- test_app_is_testing (test__config.TestTestingConfig) ... ok
-
- ----------------------------------------------------------------------
- ----------------------------------------------------------------------
- Ran 3 tests in 0.007s
-
- Ran 3 tests in 0.007s
-
- OK
- OK
Add a models.py file to the “server” directory:
将models.py文件添加到“服务器”目录中:
In the above snippet, we define a basic user model, which uses the Flask-Bcrypt extension to hash the password.
在以上代码段中,我们定义了一个基本的用户模型,该模型使用Flask-Bcrypt扩展名对密码进行哈希处理。
Install psycopg2 to connect to Postgres:
安装psycopg2以连接到Postgres:
- (env)$ pip install (env)$ pip install psycopg2psycopg2 ==== 2.6.2
- 2 .6.2
- (env)$ pip freeze > requirements.txt
- (env)$ pip freeze > requirements.txt
Within manage.py change-
在manage.py change中-
To-
至-
- from from project.server project.server import import appapp , , dbdb , , models
- models
Apply the migration:
应用迁移:
Did it work?
奏效了吗?
- (( envenv )) $ $ psql
- psql
- # # c c flask_jwt_auth
- flask_jwt_auth
- You You are are now now connected connected to to database database "flask_jwt_auth" "flask_jwt_auth" as as user user "michael.herman""michael.herman" .
- .
- # # d
-
- d
-
- List List of of relations
- relations
- Schema Schema | | Name Name | | Type Type | | Owner
- Owner
- --------+-----------------+----------+----------
- --------+-----------------+----------+----------
- public public | | alembic_version alembic_version | | table table | | postgres
- postgres
- public public | | users users | | table table | | postgres
- postgres
- public public | | users_id_seq users_id_seq | | sequence sequence | | postgres
- postgres
- (( 3 3 rowsrows )
- )
The auth workflow works as follows:
身份验证工作流程如下:
This cycle repeats until the token expires or is revoked. In the latter case, the server issues a new token.
重复此循环,直到令牌到期或被吊销为止。 在后一种情况下,服务器发出新令牌。
The tokens themselves are divided into three parts:
令牌本身分为三个部分:
We’ll dive a bit deeper into the payload, but if you’re curious, you can read more about each part from the Introduction to JSON Web Tokens article.
我们将更深入地研究有效负载,但是如果您感到好奇,可以从JSON Web令牌简介一文中阅读有关每个部分的更多信息。
To work with JSON Web Tokens in our app, install the PyJWT package:
要在我们的应用程序中使用JSON Web令牌,请安装PyJWT软件包:
Add the following method to the User()
class in project/server/models.py:
将以下方法添加到project / server / models.py中的User()
类:
- def def encode_auth_tokenencode_auth_token (( selfself , , user_iduser_id ):
- ):
- """
- """
- Generates the Auth Token
- Generates the Auth Token
- :return: string
- :return: string
- """
- """
- trytry :
- :
- payload payload = = {
-
- {
-
- 'exp''exp' : : datetimedatetime .. datetimedatetime .. utcnowutcnow () () + + datetimedatetime .. timedeltatimedelta (( daysdays == 00 , , secondsseconds == 55 ),
- ),
- 'iat''iat' : : datetimedatetime .. datetimedatetime .. utcnowutcnow (),
- (),
- 'sub''sub' : : user_id
- user_id
- }
- }
- return return jwtjwt .. encodeencode (
- (
- payloadpayload ,
- ,
- appapp .. configconfig .. getget (( 'SECRET_KEY''SECRET_KEY' ),
- ),
- algorithmalgorithm == 'HS256'
- 'HS256'
- )
- )
- except except Exception Exception as as ee :
- :
- return return e
- e
Don’t forget to add the import:
不要忘记添加导入:
So, given a user id, this method creates and returns a token from the payload and the secret key set in the config.py file. The payload is where we add metadata about the token and information about the user. This info is often referred to as JWT Claims. We utilize the following “claims”:
因此,给定用户ID,此方法会从有效负载和config.py文件中设置的密钥创建并返回令牌。 有效负载是我们添加有关令牌的元数据和有关用户的信息的地方。 此信息通常称为JWT Claims 。 我们利用以下“声明”:
exp
: expiration date of the tokeniat
: the time the token is generatedsub
: the subject of the token (the user whom it identifies)exp
:令牌的到期日期 iat
:令牌生成的时间 sub
:令牌的主题(它标识的用户) The secret key must be random and only accessible server-side. Use the Python interpreter to generate a key:
密钥必须是随机的,并且只能在服务器端访问。 使用Python解释器生成密钥:
- >>> >>> import import os
- os
- >>> >>> osos .</
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。