flask身份验证_Flask基于令牌的身份验证

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:

更新:

目标 (Objectives)

By the end of this tutorial, you will be able to…

在本教程结束时,您将能够...

  1. Discuss the benefits of using JWTs versus sessions and cookies for authentication
  2. Implement user authentication with JWTs
  3. Blacklist user tokens when necessary
  4. Write tests to create and verify JWTs and user authentication
  5. Practice test-driven development
  1. 讨论使用JWT与会话和cookie进行身份验证的好处
  2. 使用JWT实施用户身份验证
  3. 必要时将用户令牌列入黑名单
  4. 编写测试以创建和验证JWT和用户身份验证
  5. 实践测试驱动的开发

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应用程序。

介绍 (Introduction)

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的身份验证的优缺点,请查看以下文章:

  1. Cookies vs Tokens: The Definitive Guide
  2. Token Authentication vs. Cookies
  3. How do sessions work in Flask?
  1. Cookie与代币:权威指南
  2. 令牌认证与Cookie
  3. 会话在Flask中如何工作?

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是经过签名而不是加密的,因此它绝不应包含敏感信息,例如用户密码。

入门 (Getting Started)

Enough theory, let’s start implementing some code!

理论足够多,让我们开始实现一些代码!

项目设置 (Project Setup)

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>

数据库设置 (Database Setup)

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

移居 (Migrations)

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:

应用迁移:

完整性检查 (Sanity Check)

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 )
)

JWT设定 (JWT Setup)

The auth workflow works as follows:

身份验证工作流程如下:

  • Client provides email and password, which is sent to the server
  • Server then verifies that email and password are correct and responds with an auth token
  • Client stores the token and sends it along with all subsequent requests to the API
  • Server decodes the token and validates it
  • 客户端提供电子邮件和密码,并将其发送到服务器
  • 然后,服务器验证电子邮件和密码是否正确,并使用身份验证令牌进行响应
  • 客户端存储令牌并将其与所有后续请求一起发送到API
  • 服务器解码令牌并对其进行验证

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:

令牌本身分为三个部分:

  • Header
  • Payload
  • Signature
  • 标头
  • 有效载荷
  • 签名

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软件包:

编码令牌 (Encode Token)

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 token
  • iat: the time the token is generated
  • sub: 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 .</
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值