Flask Web Development Combat (Wolf Book) | Notes Chapters 1 and 2

foreword

2023-8-11

I had an idea for website development before, and I was a little eager for success. I knocked on a flask-based blog system at station B according to the video. However, it is inevitable that the code of the program will be swallowed up, and there are many places that are vague or not well understood, and it will only follow the gourd.

And when I want to develop a website, it's like crossing the river by feeling the stones. I often get stuck on many small problems. I don't know how to realize it, and I don't know what I need to learn to achieve it. For example, I want to make a chat room program, but I don't know how to display it in real time on the other side when one party sends a message. After thinking for a long time, I finally gave up.

Learning systematic and detailed knowledge has its benefits, it can wash away my feeling of groping in the dark with my bare hands. After reading the two chapters of "Wolf Book", I feel very rewarding, and many doubts before have been answered. However, everything has its own disadvantages and advantages, reading books is not easy, and requires hard work.

Someone once told me that watching videos would be more productive. Maybe he's right? But I seem to prefer the feeling that books give me. But the irony is that I have not read many books since college, and time is still running hard when I am resting, and two years have passed by in a flash. And many people are in the same predicament, right?

Back to this article, it is a reading note, mixed with a few personal thoughts but the content is not high, and the notes are scattered. It is mainly used as a personal outline memo, and it may not be of high reading value to you. If you want to learn the Flask framework, I still recommend reading the original "Wolf Book".


start

5 cases of increasing difficulty : message board SayHello, personal blog Bluelog, photo social networking site Albumy, to-do program Todoism, and chat room CatChat.

Front-end learning :

insert image description here

Many programs on the Web are inseparable from javascript, which can conveniently and concisely realize the logic and functions of many pages.

Learn about Git : https://try.github.io/

Text editor :

insert image description here

Author's blog : http://greyli.com

Git uses

Clone the code repository of this book:

git clone https://github.com/greyli/helloflask.git

View all tags contained in the current project repository:

git tag -n

Check out the code for the corresponding tagged version:

git checkout foo

The file was modified before checking out and needs to be undone:

git reset --hard

Use the diff command to compare changes between two tagged versions:

git diff foo bar

Use the git client to visually view version changes:

gitk

Regularly use the git fetch command to update the local repository:

git fetch --all
git fetch --tags
git reset --hard origin/master

Copy the new derived warehouse locally, and then freely modify the code locally:

git clone https://github.com/你的用户名/helloflask.git

1 Getting to know Flask

The web framework allows us to write web programs more conveniently without caring about the underlying request response processing.

Two main dependencies : (p3)

  • WSGI (Web Server Gateway Interface, Web Server Gateway Interface) toolset - Werkzeug (http://werkzeug.pocoo.org/)
  • Jinja2 template engine

1.1 Build a development environment

Pipenv : An enhanced version of pip, which makes package installation, package dependency management, and virtual environment management more convenient.

Create a virtual environment : In the project root directory (that is, in the helloflask folder), use pipenv installthe command. PipfileThe dependencies listed in the file will also be installed.

insert image description here

Show activated virtual environment.env : Pipenv will automatically load environment variables from files in the project directory .

# 激活
pipenv shell
# 退出
exit

Temporarily use the python interpreter in the virtual environment : (more recommended)

pipenv run python hello.py

View dependencies in the current environment :

pipenv graph

For more information about the Pipfile project, please visit its homepage.

When using pipenv installthe command to install the package, it is installed in the virtual environment. Equivalent to using pip to install packages with a virtual environment activated.

insert image description here

Update flask version : (flask-1.0.2 in the book)

pipenv update flask

Integrated development environment : pycharm professional version provides more functions for Flask development, such as creating Flask project templates, Jinja2 syntax highlighting, integration with Flask command line functions, etc.

Set up the Python interpreter (it seems that it is no longer needed): because PyCharm does not integrate support for Pipenv. (p10)

1.2 Simple example

from flask import Flask
app = Flask(__name__)

@app.route('/')
def index():
    return '<h1>Hello Flask!</h1>'

The Flask class represents a Flask program, instantiating this class will get our program instance app. __name__For the file app.py, the value is "app", which helps Flask find the required resources, such as templates and static files, in the corresponding folder. (p12)

Registering Routes : Routes are responsible for managing the mapping between URLs and functions.

  • A view function can bind multiple routes.
  • Dynamic routing : parameters can be passed and default parameters can be set.

insert image description here

Note : Flask has a built-in development server, but in the actual production environment, you need to use a production server with better performance .

Start the development server :

# 未启动虚拟环境下使用
pipenv run flask run
# 在虚拟环境中
flask run
# 命令未找到
python -m flask run

app.run()method can also start the development server, which is deprecated .

Flask looks for program instances :

  • Look for the program instance named in the file named app.pyor in the current directory .wsgi.pyapp
  • Search according to the environment variable FLASK_APP .
# 在linux
$ export FLASK_APP=hello
# 在windows
> set FLASK_APP=hello

Manage environment variables : use python-dotenvpackages, load from .envor files. .flaskenvThe .envfiles store some sensitive data.

pipenv install python-dotenv

can be .flaskenvwritten at:

# 默认为production(生产环境),开发模式将打开调试器和重载器。
FLASK_ENV=development

Use Pycharm's running configuration (instead of using the command line): in Run --> Edit Configurations (p19)

Make the server externally visible : Let LAN users access it through your internal IP. If you want public network access, you can consider intranet penetration tools, port forwarding tools, etc., such as ngrok and Localtunnel.

flask run --host=0.0.0.0

Flask environment variablesFLASK_<COMMAND>_<OPTION> : various options can be set.

Reloader : Install Watchdog. Werkzeug has a built-in stat reloader, but it consumes a lot of power and has mediocre accuracy.

# dev: 开发依赖的包
pipenv install watchdog --dev

Open PythonShell : The shell opened with flask automatically contains the program context, and the app instance has been imported.

flask shell

Flask extension : A Python library written using the interface provided by Flask. Extensions can speed up development, but also reduce flexibility and potentially bugs.

Flask project configuration : Flask-provided configuration, extension-provided, program-specific configuration may be used. They use the app.config property of the Flask object as a unified interface.

  • Flask configuration chapter: https://flask.pocoo.org/docs/latest/config/
app.config['ADMIN_NAME'] = 'Peter'
# 一次加载多个值
app.config.update()方法

URL : Used url_for()to facilitate the modification of url rules.

  • Relative url vs absolute url (p24)

Custom Flask command :

  • Click official documentation (custom command): http://click.pocoo.org/6/
@app.cli.command()
def hello():
    click.echo('Hello, Human!')
> flask hello
Hello, Human!

The name of the view function : it can be traced back to the MVC architecture, that is, "model-view-controller". But flask is not a framework for MVC architecture, because there is no built-in data model function (need to use extensions), it is more appropriate for view functions to become controller functions . (p28)

2 Flask and HTTP

Common attributes and methods of request objects : (p43)

Common attributes and methods of the Response class : (p48)

View route list : This list app.url_mapis obtained by parsing. Among them, static is a special route added by Flask to access static files.

> flask routes

Flask's built-in URL variable converter : (p37)

Transformers in URL rules : <转换器:变量名>,

@app.route('goback/<int:year>')
def go_back(year):
    return '<p>Welcome to %d!</p>' % (2018 - year)

Request hook : also known as a callback function , which can be used to register processing functions executed at different stages of request processing, such as pre-processing and post-processing , which are implemented using decorators . (p58)

Response : In most cases, we are only responsible for returning the main content of the response (not the header and various fields). Flask will call make_response()the method to convert the view function return value into a response object. Of course, the response can also contain three parts: response body, status code, and header field .

redirect(<url字符串>)Method redirection is available .

@app.route('/')
def hello_flask():
    return '', 302, {
    
    'Location':'https://www.baidu.com'}

Note : The status code is not child's play. If the above is 302changed 202, the redirection will be invalid.

Error response : used in view functions abort(<状态码>), for example:

@app.route('/404')
def not_found():
    abort(404)

Response format : In HTTP response, data can be transmitted in various formats, the default is HTML. Different MIME types can be set to identify different data formats, and the MIME types are defined in the Content-Type field.

# method 1 - 修改响应对象的属性
# @plain 纯文本
from flask import make_response
...
response = make_response("hello")
response.mimetype = 'text/plain'
# method 2 - 设置首部字段
response.headers['Content-Type'] = 'text/html; charset=utf-8'
  • XML : application/xml, generally used as the response format of AJAX request, or the response format of Web API.

  • JSON : application/json, refers to JavaScript Object Notation (JavaScript Object Notation), which is lighter and easier to parse.

    The dumps() method of the json module can serialize the dictionary, list, and tuple data in python into a json string.

# 1 - python标准库的json模块
response = make_response(json.dumps(data))
response.mimetype = 'application/json'
return response
# 2 - 使用flask包装的jsonify()函数
return jsonify(data)

Cookies : HTTP is a stateless protocol. A cookie is small text data stored on the browser, which is stored for a certain period of time, and will be attached to the next request to the same server. However, there are security risks in plaintext storage.

Set using set_cookie()method (see p68 for parameters), cookiesand get from attribute.

Session : In Flask, the session object is used to store encrypted cookies.

  • Set the program key : through Flask.secret_keyattributes; or environment variables SECRET_KEY(can be saved in files), obtained .envthrough methods in the script .getenv()
import os
app.secret_key = os.getenv('SECRET_KEY', 'secret string')

Question : Do you need to manually obtain it in the script after writing it into the environment variable? Then can I just use an environment variable name?

Question : Can't understand: Using the cookie stored in the session object, the user can see its encrypted value, but cannot modify it. Because the content in the session is signed with a key, once the data is modified, the value of the signature will also change. In this way, when reading again, the verification will fail, and the corresponding session value will also become invalid. (p51)

  • Session cookie storage time :

insert image description here

Context : There are two kinds of contexts in Flask: program context and request context .

Both contexts are automatically activated in view functions, which also means that some context-dependent functions can only be used in view functions, such as url_for(), jsonify()etc.

The program context can also be activated manually:

>>> from app import app
>>> from flask import current_app

# 方法1
>>> with app.app_context():
    ... current_app.name
   
# 方法2
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>> current_app.name
>>> app_ctx.pop()

# 激活请求上下文类似
>>> from app import app
>>> from flask import request
>>> with app.test_request_context('/hello'):
    ...

insert image description here

Doubt : How do g, request and other objects distinguish different clients?

Context hook : The callback function registered with it will be called when the program context is destroyed.

@app.teardown_appcontext
def teardown_db(exception):
    ...
    db.close()

2.1 Redirect back to the previous page

Utilize referrer or URL query parameters . (p59)

referrer : the access source. When a user clicks a link on a certain site, the browser initiates a request to the server where the new link is located, and the HTTP_REFERER field contained in the requested data records the URL of the original site where the user is located.

Doubt : The code for judging whether the url is safe or not in the book (as follows) confuses me for a long time: Since test_urlthe middle and the middle are also request.host_urlspliced, netlocisn't the last one necessarily the same?

Later I looked up urljoin(base, url)the processing mechanism of the function:

  • If urlit is a relative URL, the path part urljoinwill be obtained urlfrom it and basemerged with the obtained part;
  • If urlit is an absolute URL, urljoinit will be returned directly url.

So under what circumstances, is_safe_urlthe return value of the function is it False?

  • First, targetan absolute URL.
  • Also, the protocol or host of the absolute URL is not local.

In summary, I still feel that the logic of this function is written in a somewhat obscure way, which is not easy to understand (it must not be because I am too stupid).

def is_safe_url(target):
    ref_url = urlparse(request.host_url)
    test_url = urlparse(urljoin(request.host_url, target))
    return test_url.scheme in ('http', 'https') and \
           ref_url.netloc == test_url.netloc

2.2 Use AJAX technology to send asynchronous requests

Methods and specific usage related to AJAX in jQuery : http://api.jquery.com/category/ajax/

foreword

In traditional web applications, program operations are implemented based on a request-response cycle. Whenever the status of the page needs to change or the data needs to be updated, it will be accompanied by a request to the server. When the server responds, the entire page reloads, and a new page is rendered .

Frequent page updates can sacrifice performance and affect user experience.

AJAX refers to asynchronous Javascript and XML (Asynchronous JavaScript And XML), which is a combination of a series of technologies, such as XMLHttpRequest, JavaScript, and DOM. It makes a web program more like a program than a bunch of web resources linked with links and buttons .

AJAX operations can be implemented using jQuery : functions ajax()can send AJAX requests.

insert image description here

2.3 HTTP server push

Push technology comparison : https://stackoverflow.com/a/12855533/5511489

  • traditional polling
  • long polling
  • SSE(Server-Sent Events)
  • Websocket

2.4 Web Security Prevention

OWASP (Open Web Application Security Project, Open Web Application Security Project): https://www.owasp.org. (p66)

Common attack methods :

  • injection attack
  • XSS attack (Cross-Site Scripting, cross-site scripting): injecting code into the victim's website
  • CSRF attack : (Cross Site Request Forgery, cross-site request forgery): Forge the user's login status.

Tip : Although in actual development, it is very convenient to delete resources by adding a link to the "Delete" button, but security issues should be the first consideration when writing code, and these buttons should be embedded in form elements that use the POST method middle. Attackers cannot modify user data through GET requests.

Doubt : Did not understand the defense principle of csrf attack.


Guess you like

Origin blog.csdn.net/m0_63238256/article/details/132241086