Friday, November 1, 2024

[Flask] – Phần 6: Session và Lifetime của session là gì?

-

1. Khái niệm.

Session là một khái niệm trong phát triển web được sử dụng để theo dõi và quản lý trạng thái của một phiên làm việc (session) của người dùng trên một ứng dụng web. Session cho phép lưu trữ thông tin tạm thời và dễ dàng truy cập nó trong suốt thời gian phiên làm việc của người dùng trên trang web.

Các thông tin trong phiên làm việc thường được lưu trữ dưới dạng các cặp “khóa-giá trị” (key-value pairs). Những thông tin này có thể là các biến tạm thời như thông tin đăng nhập, giỏ hàng mua sắm, hoặc bất kỳ thông tin nào cần thiết để duy trì trạng thái của người dùng trong suốt phiên làm việc.

Lifetime của session:

  • Lifetime của một phiên làm việc (session lifetime) là khoảng thời gian mà phiên làm việc của người dùng được duy trì trên máy chủ.
  • Lifetime của session có thể được cấu hình và quản lý bởi ứng dụng web. Điều này có nghĩa rằng bạn có thể xác định khi nào phiên làm việc của người dùng sẽ hết hạn và thông tin của họ sẽ bị xoá đi.
  • Thời gian hết hạn của session có thể được xác định bằng cách sử dụng một khoảng thời gian cố định (ví dụ: 30 phút), hoặc thông qua các sự kiện như người dùng đăng xuất hoặc đóng trình duyệt.
  • Để duy trì phiên làm việc qua các yêu cầu HTTP liên tiếp từ cùng một người dùng, thông thường, một mã thông báo hoặc cookie định danh phiên (session ID) được sử dụng để liên kết các yêu cầu với cùng một phiên làm việc. Mã thông báo này thường được lưu trữ trên máy khách (trình duyệt) và được gửi đi cùng với mỗi yêu cầu để máy chủ biết đó là cùng một phiên làm việc.

Lifetime của session cần được quản lý cẩn thận để đảm bảo bảo mật và hiệu suất của ứng dụng web. Nếu một phiên làm việc tồn tại quá lâu hoặc không được quản lý cẩn thận, có thể gây rủi ro về bảo mật hoặc gây tốn tài nguyên máy chủ.

2. Xây dựng trang login.

../myapp/
├── session.py
└── templates
    ├── base.html
    ├── home.html
    └── login.html

1 directory, 4 files

Các trang base.html, home.htmllogin.html mình sẽ lấy từ bài trước. Giờ mình tạo thêm file session.py để xây dựng hàm lưu session.

Đoạn code này xử lý việc đăng nhập người dùng thông qua một biểu mẫu HTML và sử dụng phiên làm việc (session) để lưu trữ và theo dõi thông tin đăng nhập. Nếu người dùng đã đăng nhập, nó sẽ hiển thị trang chào đón, ngược lại sẽ chuyển hướng đến trang đăng nhập.

Dưới đây là giải thích cách nó hoạt động của nó:

  • @app.route(‘/login’, methods=[“POST”, “GET”]):
    • Đoạn code này đánh dấu một hàm với tên là login là một route cho đường dẫn /login.
    • Nó xác định rằng route này sẽ xử lý cả yêu cầu POST và GET (được định rõ bởi methods=["POST", "GET"]).
  • if request.method == “POST”:
    • Trong hàm login, đoạn code này kiểm tra nếu yêu cầu là loại POST (nghĩa là biểu mẫu đã được gửi đi từ trình duyệt).
  • user_name = request.form[“name”]:
    • Nếu là yêu cầu POST, nó lấy giá trị được gửi từ trường “name” trong biểu mẫu bằng cách sử dụng request.form.
  • if user_name:
    • Sau đó, nếu tên người dùng (user_name) đã được gửi, nó sẽ lưu tên người dùng vào phiên làm việc (session["user"] = user_name) và chuyển hướng đến route hello_user với tên người dùng đã đăng nhập.
  • if “user” in session:
    • Nếu không phải là yêu cầu POST (nghĩa là GET hoặc yêu cầu khác), hoặc nếu có một phiên làm việc đã được thiết lập ("user" in session), nó sẽ lấy tên người dùng từ phiên làm việc (session["user"]) và hiển thị trang chào đón với tên người dùng đã đăng nhập.
  • else:
    • Nếu không có phiên làm việc (người dùng chưa đăng nhập), nó sẽ chuyển hướng đến trang đăng nhập (login.html) bằng cách sử dụng render_templateredirect(url_for("login")).
from flask import Flask, redirect, url_for, render_template, request, session

app = Flask(__name__)
app.config["SECRET_KEY"] = "hoanghd-secret-key"

@app.route('/')
def hello_world():
    return render_template("home.html")

@app.route('/login', methods=["POST", "GET"])
def login():
    if request.method == "POST":
        user_name = request.form["name"]
        if user_name:
            session["user"] = user_name
            return redirect(url_for("hello_user", name=user_name))
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    return render_template('login.html')

@app.route('/user')
def hello_user():
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    else:
        return redirect(url_for("login"))

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=5000)

Bây giờ mình sẽ vào http://192.168.13.200:5000/loginlogin với tên HoangHD và quay trở lại trang http://192.168.13.200:5000/user thì bạn thấy kết quả trả về vẫn chào HoangHD (vì session HoangHD đã được lưu lại).

3. Xây dựng trang tính năng logout.

Thêm route logout với nội dung dưới vào session.py.

@app.route('/logout')
def logout():
    session.pop("user", None)
    return redirect(url_for("login"))

Vậy nội dung đầy đủ sau khi thêm nội dung trên sẽ như sau. Chúng ta sẽ định nghĩa một route /logout trong ứng dụng Flask và có nhiệm vụ đăng xuất người dùng khỏi phiên làm việc (session). Hãy giải thích cách nó hoạt động:

  • @app.route(‘/logout’):
    • Đoạn code này đánh dấu một hàm với tên là logout là một route cho đường dẫn /logout.
  • session.pop(“user”, None):
    • Trong hàm logout, session.pop("user", None) được sử dụng để loại bỏ thông tin người dùng khỏi phiên làm việc. Cụ thể, nó sẽ xóa giá trị có khóa "user" khỏi phiên làm việc (session). Nếu không có khóa "user" trong phiên làm việc, không có gì xảy ra (do None đã được sử dụng như giá trị mặc định).
  • return redirect(url_for(“login”)):
    • Sau khi đăng xuất thành công (xóa thông tin người dùng khỏi phiên làm việc), hàm logout sẽ chuyển hướng người dùng đến trang đăng nhập (login) bằng cách sử dụng redirect(url_for("login")).

Như vậy, khi người dùng truy cập route /logout, hàm logout sẽ được gọi, và thông tin đăng nhập của người dùng sẽ bị xóa khỏi phiên làm việc, đồng thời họ sẽ được chuyển hướng đến trang đăng nhập (login). Điều này có nghĩa là người dùng đã đăng xuất và cần phải đăng nhập lại để truy cập các phần có yêu cầu đăng nhập.

from flask import Flask, redirect, url_for, render_template, request, session

app = Flask(__name__)
app.config["SECRET_KEY"] = "hoanghd-secret-key"

@app.route('/')
def hello_world():
    return render_template("home.html")

@app.route('/login', methods=["POST", "GET"])
def login():
    if request.method == "POST":
        user_name = request.form["name"]
        if user_name:
            session["user"] = user_name
            return redirect(url_for("hello_user", name=user_name))
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    return render_template('login.html')

@app.route('/user')
def hello_user():
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    else:
        return redirect(url_for("login"))

@app.route('/logout')
def logout():
    session.pop("user", None)
    return redirect(url_for("login"))

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=5000)

Kết quả hiện tại HoangHD đang được lưu nên khi bạn truy cập http://192.168.13.200:5000/user thì sẽ có nội dung chào HoangHD, giờ bạn vào http://192.168.13.200:5000/logout thì hàm logout sẽ được thực thi và sau đó bạn truy cập lại trang http://192.168.13.200:5000/user thì trình duyệt sẽ đưa bạn quay trở lại trang http://192.168.13.200:5000/login.

4. Cài đặt lại Lifetime của session.

Mặc định Lifetime của session sẽ lưu 30 ngày và thực tế không ai lưu lâu như vậy cả, chúng ta có thể điều chỉnh lại Lifetime của session nếu chúng ta muốn.

Thêm module from datetime import timedelta.

Chỉnh lại code app.permanent_session_lifetime = timedelta(minutes=1)session.permanent = True.

Vậy nội dung sau khi sửa đổi sẽ là.

  • from datetime import timedelta: Dòng này import lớp timedelta từ module datetime. timedelta được sử dụng để biểu thị một khoảng thời gian dựa trên các đơn vị thời gian như giây, phút, giờ, ngày, và nhiều đơn vị khác.
  • app.permanent_session_lifetime = timedelta(minutes=1): Dòng này đặt thời gian tồn tại của phiên làm việc là 1 phút. Điều này có nghĩa là sau khi người dùng đăng nhập hoặc thực hiện một hành động nào đó, phiên làm việc của họ sẽ tồn tại trong vòng 1 phút kể từ thời điểm đó. Sau 1 phút, phiên làm việc sẽ hết hạn và người dùng sẽ phải đăng nhập lại.
  • session.permanent = True: Dòng này đặt phiên làm việc là phiên làm việc vĩnh viễn (permanent). Khi bạn đặt session.permanent = True, phiên làm việc của người dùng sẽ không bao giờ hết hạn sau một khoảng thời gian cố định (như khi bạn đặt app.permanent_session_lifetime). Phiên làm việc sẽ được duy trì cho đến khi người dùng đăng xuất hoặc xóa nó.
from flask import Flask, redirect, url_for, render_template, request, session
from datetime import timedelta

app = Flask(__name__)
app.config["SECRET_KEY"] = "hoanghd-secret-key"
app.permanent_session_lifetime = timedelta(minutes=1)

@app.route('/')
def hello_world():
    return render_template("home.html")

@app.route('/login', methods=["POST", "GET"])
def login():
    if request.method == "POST":
        user_name = request.form["name"]
        session.permanent = True
        if user_name:
            session["user"] = user_name
            return redirect(url_for("hello_user", name=user_name))
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    return render_template('login.html')

@app.route('/user')
def hello_user():
    if "user" in session:
        name = session["user"]
        return f"<h1>Hello {name}!</h1>"
    else:
        return redirect(url_for("login"))

@app.route('/logout')
def logout():
    session.pop("user", None)
    return redirect(url_for("login"))

if __name__ == "__main__":
    app.run(debug=True, host='0.0.0.0', port=5000)

Trong ví dụ này, chúng ta đã đặt thời gian tồn tại của phiên làm việc là 1 phút và làm cho phiên làm việc trở thành phiên làm việc vĩnh viễn. Điều này có thể hữu ích trong một số tình huống, nhưng chúng ta cần cân nhắc về bảo mật và hiệu suất khi đặt thời gian tồn tại và loại phiên làm việc.

Bây giờ bạn hãy login và chờ 1 phút, bạn tải lại trang thì người dùng HoangHD sẽ bị chấm dứt session.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories