Mã đăng nhập python

Python là một ngôn ngữ lập trình mạnh mẽ, dễ học. Nó có cấu trúc dữ liệu cấp cao hiệu quả và cách tiếp cận đơn giản nhưng hiệu quả đối với lập trình hướng đối tượng. Cú pháp tao nhã và kiểu gõ động của Python, cùng với bản chất diễn giải của nó, làm cho nó trở thành ngôn ngữ lý tưởng để viết kịch bản và phát triển ứng dụng nhanh chóng trong nhiều lĩnh vực trên hầu hết các nền tảng

Trình thông dịch Python và thư viện chuẩn mở rộng có sẵn miễn phí ở dạng nguồn hoặc nhị phân cho tất cả các nền tảng chính từ trang web Python, https. //www. con trăn. org/, và có thể được phân phối tự do. Trang web tương tự cũng chứa các bản phân phối và con trỏ tới nhiều mô-đun, chương trình và công cụ Python miễn phí của bên thứ ba và tài liệu bổ sung

Trình thông dịch Python dễ dàng mở rộng với các hàm và kiểu dữ liệu mới được triển khai trong C hoặc C++ (hoặc các ngôn ngữ khác có thể gọi được từ C). Python cũng phù hợp làm ngôn ngữ mở rộng cho các ứng dụng có thể tùy chỉnh

Hướng dẫn này giới thiệu cho người đọc một cách không chính thức các khái niệm và tính năng cơ bản của ngôn ngữ và hệ thống Python. Sẽ rất hữu ích khi có một trình thông dịch Python tiện dụng cho trải nghiệm thực hành, nhưng tất cả các ví dụ đều độc lập, vì vậy hướng dẫn cũng có thể được đọc ngoại tuyến

Để biết mô tả về các đối tượng và mô-đun tiêu chuẩn, hãy xem. đưa ra một định nghĩa chính thức hơn về ngôn ngữ. Để viết các phần mở rộng trong C hoặc C++, hãy đọc và. Ngoài ra còn có một số cuốn sách chuyên sâu về Python

Hướng dẫn này không cố gắng toàn diện và bao gồm mọi tính năng đơn lẻ hoặc thậm chí mọi tính năng thường được sử dụng. Thay vào đó, nó giới thiệu nhiều tính năng đáng chú ý nhất của Python và sẽ cho bạn ý tưởng hay về hương vị và phong cách của ngôn ngữ. Sau khi đọc nó, bạn sẽ có thể đọc và viết các mô-đun và chương trình Python, đồng thời bạn sẽ sẵn sàng tìm hiểu thêm về các mô-đun thư viện Python khác nhau được mô tả trong

Trong phần này, chúng ta sẽ tìm hiểu những cách làm nào để tạo ra một hệ thống đăng nhập người dùng cho ứng dụng

Để giúp các bạn dễ theo dõi, sau đây là danh sách các bài viết trong chuỗi bài hướng dẫn này

  • Phần 1. Chào thế giới
  • Phần 2. Tìm hiểu về mẫu
  • Phần 3. Tìm hiểu về Web Forms
  • Phần 4. Sử dụng cơ sở dữ liệu
  • Phần 5. Xử lý đăng nhập (Bài viết này)
  • Phần 6. Hồ sơ cá nhân và ảnh đại diện
  • Phần 7. Xử lý lỗi
  • Phần 8. Tạo chức năng theo dõi
  • Phần 9. Partition
  • Phần 10. email hỗ trợ
  • Phần 11. Nâng cấp giao diện
  • Phần 12. Xử lý thời gian
  • Phần 13. Hỗ trợ đa ngôn ngữ
  • Phần 14. Sử dụng Ajax
  • Phần 15. Tinh chỉnh cấu trúc ứng dụng
  • Phần 16. Hỗ trợ tìm kiếm hỗ trợ
  • Phần 17. Triển khai ứng dụng trên Linux
  • Phần 18. Triển khai ứng dụng với Heroku
  • Phần 19. Triển khai ứng dụng với Docker
  • Phần 20. JavaScript nâng cao
  • Phần 21. Thông báo cho người sử dụng
  • Phần 22. Tìm hiểu về nhiệm vụ nền
  • Phần 23. Xây dựng API

Bạn có thể truy cập mã nguồn cho phần này tại GitHub

Trước đây, chúng ta đã tạo ra một biểu mẫu đăng nhập trong Phần 3 và tìm hiểu cách sử dụng cơ sở dữ liệu trong Phần 4. Tiếp theo, chúng ta sẽ phân phối các kiến ​​thức đã học trong hai phần trước để tạo ra một hệ thống đăng nhập thông tin người dùng đơn giản

Mã băm cho mật khẩu của người dùng (Password hashing)

Trong Phần 4, chúng ta đã định nghĩa trường password_hash trong cấu hình người dùng dữ liệu. Trường này được sử dụng để chứa mã băm cho mã mật của người dùng (Để đảm bảo tính chắc chắn nhất, từ đây chúng tôi sẽ sử dụng thuật ngữ người dùng thay cho người dùng). Mã băm này sẽ được sử dụng để xác thực mật mã mà người dùng nhập vào trong quá trình đăng nhập. Quá trình và những nguyên lý tạo ra hash rất phức tạp và chỉ có các chuyên gia về bảo mật mới hiểu, vì thế chúng ta sẽ không đi sâu vào chi tiết ở đây. Tuy nhiên, chúng ta có thể sử dụng một số thư viện Flask để tạo ra hàm băm một cách dễ dàng và nhanh chóng.

Trong các thư viện của Flask, có một gói cung cấp các phương thức để làm việc với tên băm là Werkzeug. Nếu để ý quá trình cài đặt Flask, bạn có thể thấy tên của gói này ở đâu trong các thông báo mà Flask in ra trong suốt quá trình cài đặt bởi vì gói này là một trong những thành phần quan trọng nhất của Flask. Cũng vì lý do đó, Werkzeug đã được cài đặt sẵn trong môi trường ảo của bạn ngay từ đầu. Ví dụ sau sẽ minh họa cách tạo hàm băm cho mật mã bằng thư viện Werkzeug

1

2

3

4

>>> từ werkzeug. bảo mật nhập generate_password_hash

>>> hash = generate_password_hash('foobar')

>>> băm

'pbkdf2. sha256. 150000$3HUtwgW8$39ae9f2f4925661c5cf9cfa04842b04b874730f87739f65316eb6e85f4678c28'

Trong ví dụ trên, chuỗi mật mã “foobar” ban đầu được chuyển đổi thành một chuỗi mã dài bằng các phương thức mã hóa không thể đảo ngược, có nghĩa là bạn sẽ không thể chuyển đổi chuỗi mã này thành mã ban đầu mật mã bằng . Too this call is hash (hash). Và hơn thế nữa, nếu bạn tiếp tục băm một mật mã nhiều lần, bạn sẽ nhận được nhiều kết quả khác nhau. Vì vậy, bạn sẽ không thể xác định được hai người dùng có cùng mã mật hay không nếu chỉ nhìn vào giá trị băm từ mật mã của họ

Để xác thực mã mật khẩu (xác minh), chúng ta sử dụng hàm thứ hai từ thư viện Werkzeug như trong ví dụ sau

1

2

3

4

5

>>> từ werkzeug. bảo mật nhập check_password_hash

>>> check_password_hash(băm, 'foobar')

ĐÚNG VẬY

>>> check_password_hash(băm, 'barfoo')

Sai

Quá trình xác thực sẽ nhận mã mật khẩu do người dùng nhập vào, chuyển đổi thành mã băm và so sánh với mã băm được sinh ra từ mã cấm đầu tiên và được lưu lại trong cơ sở dữ liệu. Nếu mã băm từ mật mã nhập vào giống với mã băm đã được lưu trữ, hàm sẽ trả về True, ngược lại nó sẽ trả về False

Quá trình tạo hàm băm và xác thực mã mật khẩu sẽ được thêm vào hai phương thức mới trong mô hình người dùng như sau

ứng dụng/mô hình. py. Tạo mã băm và xác thực mã bảo mật

1

2

3

4

5

6

7

8

9

10

11

12

từ werkzeug. bảo mật nhập generate_password_hash, check_password_hash

 

.. .

 

lớp Người dùng(db. Mô hình).

    . . .

 

    def set_password(self, password):

        bản thân. password_hash = generate_password_hash(password)

 

    def check_password(self, password):

        return check_password_hash(self.password_hash, mật khẩu)

Với hai phương thức này, một đối tượng người dùng có thể xác thực mã mật khẩu của mình. Sau đây là một ví dụ về cách sử dụng hai phương thức này

1

2

3

4

5

6

>>> u = Người dùng(username='thai', email='[email protected]')

>>> u. set_password('mypassword')

>>> u. check_password('anotherpassword')

Sai

>>> u. check_password('mypassword')

ĐÚNG VẬY

Giới thiệu về Flask-Login

Trong phần này, chúng ta cũng sẽ tìm hiểu thêm một Flask thư viện mở rộng rất phổ biến là Flask-Login

Thư viện mở rộng này quản lý trạng thái đăng nhập của người dùng. Nhờ đó, hệ thống có thể ghi nhớ các thông tin về người dùng đã đăng nhập trong một phiên làm việc của viện và cho phép họ truy cập các trang Web yêu cầu người dùng phải đăng nhập. Nó cung cấp chức năng “Remember me” để người dùng vẫn giữ trạng thái đăng nhập ngay cả khi họ đã đóng trình duyệt. Để bắt đầu phần này, chúng ta hãy cài đặt Flask-Login trong môi trường ảo của bạn

1

(myenv) $ pip3 install flask-login

Tương tự như các thư viện mở rộng khác, Flask-Login phải được khởi tạo ngay sau khi có thể ứng dụng trong tệp app/__init__. py as after

ứng dụng/__init__. py. Khởi tạo Flask-Đăng nhập

1

2

3

4

5

6

7

8

.. .

từ flask_login nhập Trình quản lý đăng nhập

 

app = Flask(__name__)

.. .

đăng nhập = Trình quản lý đăng nhập(ứng dụng)

 

.. .

Điều chỉnh mô hình dữ liệu người dùng (User) cho Flask-Login

Flask-Login thư viện sẽ làm việc với người dùng mô hình dữ liệu với một số thuộc tính và phương thức định sẵn. Đây là một thiết kế hay bởi vì nếu các thuộc tính và phương thức này được cung cấp trong mô hình dữ liệu, Flask-Login sẽ thực hiện đúng theo yêu cầu bất chấp các điều kiện khác nhau. Ví dụ như nó có thể hoạt động với người dùng mô hình dữ liệu từ bất kỳ hệ thống cơ sở dữ liệu nào

Sau đây là bốn yêu cầu của Flask-Login với người dùng mô hình dữ liệu

  • is_authenticated. một thuộc tính sẽ được gán là Đúng nếu người dùng có tên và mã mã hợp lệ, Sai nếu một trong hai không đúng
  • is_active. một thuộc tính được gán là True nếu tài khoản người dùng trong chế độ hoạt động (đang hoạt động) và False nếu đảo ngược
  • is_anonymous. một thuộc tính được gán là Sai đối với những người dùng bình thường và Đúng đối với những người dùng ẩn danh (ẩn danh)
  • get_id(). một phương thức để trả lại danh sách người dùng (id) dưới dạng chuỗi

Chúng ta có thể viết mã cho yêu cầu này một cách dễ dàng. Nhưng bởi vì những yêu cầu này tương đối tổng quát, Flask-Login cung cấp một lớp mixin được gọi là UserMixin(Nếu chưa hiểu về khái niệm mixin trong Python, bạn có thể tham khảo tại đây). Lớp này có sẵn các khai báo và mã thực thi có thể sử dụng được với phần lớn mô hình dữ liệu Người dùng. Sau đây là cách thêm lớp mixin vào mô hình dữ liệu

ứng dụng/mô hình. py. mixin layer for user in Flask-Login

1

2

3

4

5

.. .

từ flask_login nhập UserMixin

 

lớp Người dùng(UserMixin, db.Mô hình).

    . . .

Hàm tải thông tin người dùng

Flask-Login theo dõi trạng thái của những người dùng đã đăng nhập bằng cách lưu các ID tương ứng trong các phiên làm việc (phiên người dùng) – một vùng lưu trữ được xác định cho mỗi người dùng đang kết nối vào ứng dụng. Mỗi khi người dùng đăng nhập truy cập một trang mới trong ứng dụng, Flask-Login sẽ lấy ID của người dùng đó từ phiên làm việc và tải dữ liệu về người dùng đó vào bộ nhớ

Bởi vì Flask-Login không trực tiếp làm việc với cơ sở dữ liệu, nó cần có sự trợ giúp của các thành phần khác nhau trong ứng dụng để tìm kiếm và tải dữ liệu về người dùng. Vì vậy, thư viện này cần có một chức năng hỗ trợ để tải thông tin người dùng. Hàm này sẽ tìm kiếm và tải các thông tin về người dùng từ cơ sở dữ liệu dựa trên Id của người dùng đó. Chúng ta sẽ thêm mã cho chức năng này vào mô-đun ứng dụng/mô hình. py as after

ứng dụng/mô hình. py. Hàm tải dữ liệu người dùng cho Flask-Login

1

2

3

4

5

6

từ ứng dụng nhập đăng nhập

.. .

 

@đăng nhập. user_loader

def load_user(id):

    trả lại Người dùng. truy vấn. lấy(int(id))

Chúng ta sẽ đăng ký chức năng này với Flask-Login qua decorator @login.user_loader. Tham số id sẽ được truyền vào hàm này dưới dạng chuỗi (Chuỗi), vì vậy nếu cơ sở dữ liệu định dạng Id dạng số nguyên (số nguyên), chúng ta sẽ phải chuyển đổi Id thành số nguyên như trong ví dụ ở trên

Đăng nhập người dùng

Sau các bước chuẩn bị ở trên, chúng ta có thể quay lại với hàm hiển thị đăng nhập mà chúng ta đã tạo ra trong Phần 3. Lưu ý là tại thời điểm này, hàm này không có chức năng đăng nhập thực tế mà chỉ đưa ra một thông báo nhờ hàm flash() nếu người dùng nhập đầy đủ tên người dùng và mã mật (với bất kỳ giá trị nào). Hiện tại, sau khi đã có cơ sở dữ liệu và biết cách tạo ra hàm băm cho mã mật, chúng ta có thể làm cho nó thực sự hoạt động

ứng dụng/tuyến đường. py. Hàm hiển thị đăng nhập

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

.. .

từ flask_login nhập current_user, login_user

từ ứng dụng. mô hình nhập Người dùng

 

.. .

 

@ứng dụng. tuyến đường('/đăng nhập', methods=['GET', 'POST'])

def đăng nhập().

    if current_user. is_authenticated.

        trả lại chuyển hướng(url_for('index'))

    biểu mẫu = Biểu mẫu đăng nhập()

    nếu biểu mẫu. validate_on_submit().

        người dùng = Người dùng. truy vấn. filter_by(tên người dùng=biểu mẫu . .tên người dùng. dữ liệu). đầu tiên()

        nếu người dùng Không có or not user.check_password(biểu mẫu. mật khẩu. dữ liệu).

            flash('Tên người dùng hoặc mật khẩu không hợp lệ')

            return redirect(url_for('login'))

        login_user(user, remember=form.nhớ_tôi. dữ liệu)

        trả lại chuyển hướng(url_for('index'))

    return render_template('đăng nhập. html', tiêu đề='Đăng nhập', form=form)

Trong hai dòng lệnh đầu tiên của hàm True0, chúng ta sẽ giải quyết vấn đề khi có một người dùng đã đăng nhập thành công nhưng truy cập lại vào trang /đăng nhập vì lý do nào đó. Dù về mặt lập trình, điều này không có gì sai, nhưng đây là điều không hay cho người dùng (theo nguyên tắc thiết kế ứng dụng, để có UX – User eXperience hay trải nghiệm của người dùng – tốt thì người dùng không nên . Vì vậy, trong trường hợp này, chúng tôi sẽ sử dụng giải pháp để chuyển hướng người dùng của họ trở lại trang chủ (với URL /index) nếu đây là người dùng đã đăng ký và được hệ thống xác nhận (đăng nhập thành công . Để làm được điều này, chúng ta cần sự trợ giúp của biến True1 có sẵn trong Flask-Login. Nếu người dùng đã đăng nhập, biến này sẽ chứa các thông tin về người dùng từ cơ sở dữ liệu (việc tải thông tin của người dùng từ cơ sở dữ liệu được thực hiện thông qua hàm True2 mà chúng tôi đã tạo ra ở trên). Trong trường hợp người dùng chưa đăng nhập, biến này sẽ chứa giá trị đại diện cho người dùng ẩn danh (ẩn danh). Ngoài ra, biến này còn thuộc tính is_authenticated rất hữu ích để giúp xác định người dùng có đăng nhập hay không. Đoạn mã của chúng ta sẽ kiểm tra thuộc tính này, và nếu nó trả về True – đồng nghĩa đây là người dùng đã đăng nhập thành công – thì chúng ta sẽ chuyển hướng đến và hiển thị trang chủ thay vì hiển thị trang đăng nhập

Trước đây, chúng tôi cũng sử dụng hàm flash() để hiển thị một thông báo là người sử dụng đăng nhập thành công mà không thực hiện các tiến trình quá trình đăng nhập. Nhưng lần này thì chúng ta có thể thay thế mã giả này bằng mã thật cho quá trình đăng nhập. Để làm điều này, trước khi hết, chúng ta cần tải dữ liệu về người dùng từ cơ sở dữ liệu. Thông qua hình thức đăng nhập, chúng ta sẽ nhận được tên người dùng. Giá trị này sẽ được sử dụng để tìm Id tương ứng của người dùng này trong cơ sở dữ liệu bằng hàm True5 của truy vấn đối tượng (truy vấn) trong thư viện SQLAlchemy. Hàm filter_by sẽ trả về các đối tượng có giá trị tên người dùng khớp với tên người dùng mà chúng ta đã sử dụng. Bởi vì chúng ta biết rằng tên người dùng mang tính duy nhất nên chỉ có tối đa một đối tượng người dùng trong cơ sở dữ liệu có tên người dùng trùng với tên người dùng mà chúng ta đang tìm kiếm. Do đó, chúng ta có thể sử dụng hàm True6, hàm này sẽ trả về một kết quả nếu có một người dùng như vậy hoặc Không có người dùng nào nếu không tồn tại trong cơ sở dữ liệu. Trong Phần 4, chúng ta đã thấy kết quả khi gọi hàm True7 trong một truy vấn. nó sẽ trả về tất cả các kết quả trùng khớp với truy vấn đó trong cơ sở dữ liệu. Hàm True6 thường được sử dụng trong trường hợp chúng ta biết trước chỉ có thể đạt được kết quả tối đa

Nếu chúng tôi tìm thấy một người dùng từ cơ sở dữ liệu có cùng tên người dùng như trong biểu mẫu đăng nhập, chúng tôi sẽ tiến hành các bước tiếp theo là kiểm tra mã mật khẩu. Quá trình này được thực hiện bằng cách sử dụng hàm True9 mà chúng ta đã nói ở phần đầu của bài này. Hàm này sẽ tạo hàm băm từ mã mật mã do người dùng nhập vào và so sánh với giá trị password_hash từ bảng Người dùng. Nếu hai giá trị này giống nhau thì mật mã do người dùng nhập vào là đúng (hợp lệ), ngược lại thì mật mã này là sai (không hợp lệ). Như vậy, cuối cùng chúng ta có hai khả năng người dùng không được phép đăng nhập. tên người dùng hoặc mật khẩu nhập vào là sai. Trong cả hai trường hợp, chúng ta sẽ sử dụng flash() để hiển thị một thông báo lỗi và chuyển hướng về trang đăng nhập để người dùng có thể nhập các thông tin lần nữa

Nếu tên người dùng và mật khẩu tương ứng đúng, chúng ta sẽ gọi một hàm trong thư viện Flask-Login là False2 để ghi nhận trạng thái của người dùng này là đã đăng nhập thành công. Điều này cũng đồng nghĩa với việc ứng dụng sẽ tải và lưu giữ các thông tin về người dùng từ cơ sở dữ liệu vào bộ nhớ và lưu giữ các thông tin này trong suốt thời gian làm việc của người dùng (cho đến khi người dùng đăng xuất – đăng xuất – thoát khỏi . Nhờ đó, khi người dùng truy cập bất kỳ trang nào, ứng dụng cũng có thể dễ dàng tìm thấy thông tin về chúng thông qua biến True1

Sau khi người dùng đăng nhập thành công, chúng ta sẽ chuyển (chuyển hướng) người dùng đến trang chủ

Đăng xuất (Log Out)

Để hoàn tất quá trình xuất nhập, chúng ta cũng phải cung cấp chức năng đăng xuất (đăng xuất) ra khỏi ứng dụng. Chúng ta sẽ sử dụng một chức năng khác của thư viện Flask-Login được gọi là False4 cho mục đích này

ứng dụng/tuyến đường. py. Hàm hiển thị Đăng xuất

1

2

3

4

5

6

7

8

9

.. .

từ flask_login nhập đăng xuất_user

 

.. .

 

@ứng dụng. tuyến đường('/logout')

def đăng xuất().

    logout_user()

    return redirect(url_for('index'))

Chúng ta cũng cần thay thế liên kết Đăng nhập trong thay đổi hướng bằng liên kết Đăng xuất sau khi người dùng đăng nhập thành công. Chúng ta sẽ làm điều này bằng cách cập nhật cơ sở tập tin. html

ứng dụng/mẫu/cơ sở. html. Hiển thị liên kết đăng nhập và đăng xuất trên thanh định hướng

1

2

3

4

5

6

7

8

9

    

Blog của tôi

        href="{{ url_for(>Home

{% nếu current_user. is_anonymous %}

        href="{{ url_for(>Login

{% khác %}

        href="{{ url_for(>Logout

{% endif %}

    

Như đã nói ở trên, thuộc tính is_anonymous được thư viện Flask-Login cung cấp qua lớp UserMixin. Biểu thức False7 sẽ có giá trị True khi người dùng chưa đăng nhập

Yêu cầu người dùng đăng nhập

Flask-Login có một chức năng rất hữu ích để yêu cầu người dùng đăng nhập nếu họ muốn truy cập vào một số trang định sẵn trong ứng dụng. Nếu người dùng không đăng nhập để tìm cách truy cập các trang này, Flask-Login sẽ tự động chuyển họ đến trang đăng nhập và quay lại trang được yêu cầu truy cập sau khi người dùng đã đăng nhập thành công

Để sử dụng chức năng này, Flask-Login cần biết hàm hiển thị cho quá trình đăng nhập. Chúng ta sẽ thay đổi file app/__init__. py to make this thing

1

2

3

.. .

đăng nhập = Trình quản lý đăng nhập(ứng dụng)

đăng nhập. login_view = 'đăng nhập'

Giá trị ‘False9‘ ở trên là tên của hàm hiển thị đăng nhập. Hay nói cách khác, đó là tên bạn sẽ sử dụng khi gọi hành động is_authenticated0 để lấy giá trị của URL

Chúng ta sẽ sử dụng decorator is_authenticated1 cho các hàm hiển thị nào chỉ cho phép người dùng đăng nhập truy cập. Khi bạn thêm trình trang trí này vào một hàm hiển thị và trình trang trí bên dưới @app. route, this function will be protected and not allow the user not posted access truy cập. Sau đây là ví dụ về chức năng hiển thị cho trang chủ của ứng dụng

ứng dụng/tuyến đường. py. người trang trí is_authenticated1

1

2

3

4

5

6

7

từ flask_login nhập đăng nhập_required

 

@ứng dụng. tuyến đường('/')

@ứng dụng. tuyến đường('/index')

@login_required

def index().

    . . .

Chúng ta cần làm một việc nữa là thêm tính năng trở về trang mà người dùng yêu cầu truy cập sau khi đã đăng nhập thành công. Khi một người dùng chưa đăng nhập truy cập vào một trang được hiển thị bởi một hàm hiển thị đã được bảo vệ bởi trang trí is_authenticated1, trang trí này sẽ chuyển hướng người dùng đó đến trang đăng nhập, nhưng nó sẽ thêm vào một vài thông số để ứng dụng . Ví dụ như khi người dùng muốn truy cập trang /index khi chưa đăng nhập, trang trí is_authenticated1 sẽ kiểm tra yêu cầu này và chuyển hướng người dùng đến /login, nhưng nó sẽ thêm một số tham số vào URL của trang /login như sau. /login?next=/index. Tham số tiếp theo trong URL này sẽ được gán giá trị của URL được yêu cầu cấm ban đầu, nhờ đó ứng dụng biết sẽ phải quay lại trang /index sau khi người dùng đăng nhập thành công

Sau đây là đoạn mã để đọc và xử lý tham số is_authenticated5

ứng dụng/tuyến đường. py. Chuyển hướng đến trang tại “tiếp theo”

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

từ bình nhập yêu cầu

từ werkzeug. url nhập url_ phân tích cú pháp

 

@ứng dụng. tuyến đường('/đăng nhập', methods=['GET', 'POST'])

def đăng nhập().

    . . .

    nếu biểu mẫu. validate_on_submit().

        người dùng = Người dùng. truy vấn. filter_by(tên người dùng=biểu mẫu . .tên người dùng. dữ liệu). đầu tiên()

        nếu người dùng Không có or not user.check_password(biểu mẫu. mật khẩu. dữ liệu).

            flash('Tên người dùng hoặc mật khẩu không hợp lệ')

            return redirect(url_for('login'))

        login_user(user, remember=form.nhớ_tôi. dữ liệu)

        trang_tiếp theo = yêu cầu. đối số. lấy('tiếp theo')

        nếu không trang_tiếp theo hoặc url_parse(next_page).netloc . = ''.

            trang_tiếp theo = url_for('index')

        trả lại chuyển hướng(trang tiếp theo)

    . . .

Ngay sau khi hàm False2 trả về kết quả là người dùng đăng nhập thành công, chúng ta sẽ lấy giá trị của tham số is_authenticated5 trong URL. Flask cung cấp biến is_authenticated8 với tất cả thông tin được người dùng nhập vào và gửi qua trình duyệt. Cụ thể là thuộc tính is_authenticated9 trả về tất cả các tham số được thêm vào URL trong từ điển. Có ba khả năng cần được xem xét để quyết định sẽ chuyển hướng đến vị trí bất kỳ sau khi người dùng đăng nhập thành công

  • Nếu URL đăng nhập không có tham số is_authenticated5, người dùng sẽ được chuyển hướng đến trang chủ (/index) theo mặc định
  • Nếu URL đăng nhập có tham số tiếp theo được gán với giá trị là một đường dẫn tương đối (hay nói cách khác là một URL không có phần miền -tên miền), người dùng sẽ được chuyển hướng đến URL đó
  • Nếu URL đăng nhập có tham số tiếp theo được gán với giá trị là một URL đầy đủ với cả tên miền, người dùng sẽ được chuyển hướng đến trang chủ của ứng dụng

Trường hợp đầu và trường hợp thứ hai đối tượng dễ hiểu. Trường hợp thứ ba Đảm bảo chắc chắn cho ứng dụng được bảo mật hơn. Một người có ý định có thể đặt một URL dẫn đến một trang Web nguy hiểm vào trong tham số tiếp theo, vì như vậy, ứng dụng chỉ chuyển hướng khi gặp đường dẫn tương đối, nhờ đó đảm bảo rằng mọi trang Web đều được chuyển đến đồng đều . Để phân biệt các URL tương đối và đầy đủ, chúng ta sử dụng hàm is_active1 từ thư viện Werkzeug và kiểm tra xem thành phần is_active2 có được gán hay không

Hiển thị người dùng đã đăng nhập trong các mẫu

Bạn còn nhớ trong Phần 2 chúng ta đã tạo ra một người dùng giả để mô phỏng hệ thống đăng nhập người dùng khi thiết kế trang chủ khi chúng ta chưa có hệ thống này hay không? . Thay vì người dùng giả, chúng ta có thể sử dụng biến True1 trong các mẫu

ứng dụng/mẫu/chỉ mục. html. Truyền thông tin về người dùng đang đăng nhập vào mẫu

1

2

3

4

5

6

7

8

{% mở rộng "cơ sở. html" %}

 

{% chặn nội dung %}

    

Xin chào, {{ current_user. tên tài khoản }}.

{% cho bài đăng trong bài viết %}

    

{{ post. tác giả. tên tài khoản }}. {{ bài đăng. nội dung }}

    {% endfor %}

{% chặn kết thúc %}

Chúng ta cũng có thể loại bỏ tham số is_active4 trong các hàm hiển thị

ứng dụng/tuyến đường. py. Không truyền tham số is_active4 đến các mẫu nữa

1

2

3

4

5

@ứng dụng. tuyến đường('/')

@ứng dụng. tuyến đường('/index')

def index().

    . . .

    return render_template("index. html", tiêu đề='Trang chủ', posts=posts)

Đây là lúc để kiểm tra chức năng đăng nhập và đăng xuất làm việc thế nào. Bởi vì chúng ta chưa có chức năng đăng ký người dùng, cách duy nhất để thêm người dùng vào cơ sở dữ liệu là sử dụng chế độ dòng lệnh của Python. Chúng ta hãy bắt đầu bằng cách gọi is_active6 và sử dụng các lệnh sau đây để đăng ký một người dùng với hệ thống

1

2

3

4

>>> u = Người dùng(username='thai', email='[email protected]')

>>> u. set_password('thaipham')

>>> db. phiên. thêm(u)

>>> db. phiên. cam kết()

Bây giờ, nếu bạn chạy ứng dụng và truy cập địa chỉ http. //máy chủ cục bộ. 5000/ hoặc http. //máy chủ cục bộ. 5000/index, ứng dụng sẽ lập tức chuyển hướng bạn đến trang đăng nhập. Và sau khi đã nhập các thông tin về người dùng mà bạn đã thêm vào trong cơ sở dữ liệu, bạn sẽ được chuyển hướng đến trang mà bạn yêu cầu và một lời chào mừng sẽ được hiển thị

Đăng ký người dùng

Chức năng cuối cùng mà chúng ta sẽ xây dựng trong bài viết hôm nay là biểu mẫu đăng ký để người dùng mới có thể đăng ký và đăng nhập vào ứng dụng. Chúng ta sẽ cần tạo ra một lớp biểu mẫu web mới trong ứng dụng/biểu mẫu. py

ứng dụng/biểu mẫu. py. biểu mẫu đăng ký người dùng

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

từ flask_wtf nhập FlaskForm

từ wtforms nhập StringField, PasswordField, BooleanField, SubmitField

từ wtforms. trình xác thực nhập Lỗi xác thực, Bắt buộc dữ liệu, Email, EqualTo

từ ứng dụng. mô hình nhập Người dùng

 

.. .

 

class Mẫu đăng ký(FlaskForm):

    tên người dùng = StringField('Username', validators=[DataRequired()])

    email = StringField('Email', validators=[DataRequired(), Email()])

    mật khẩu = Trường mật khẩu('Password', validators=[DataRequired()])

    password2 = Trường mật khẩu(

        'Lặp lại mật khẩu', trình xác thực=[DataRequired(), EqualTo('password')])

    gửi = Trường gửi('Register')

 

   def validate_username(self, username):

        người dùng = Người dùng. truy vấn. filter_by(tên người dùng=tên người dùng . .dữ liệu). đầu tiên()

        nếu người dùng không None:

            nâng cao Lỗi xác thực('Vui lòng sử dụng tên người dùng khác. ')

 

    def validate_email(self, email):

        người dùng = Người dùng. truy vấn. filter_by(email=email . .dữ liệu). đầu tiên()

        nếu người dùng không None:

            tăng Lỗi xác thực('Vui lòng sử dụng một email khác . ')

Có vài điểm đáng lưu ý liên quan đến việc kiểm tra dữ liệu đầu vào trong biểu mẫu mới này. Đầu tiên, chúng ta thêm một biến kiểm tra dữ liệu (validator) thứ hai bên ngoài is_active7 vào trường is_active8. BIến gọi này là Email. Đây là một biến kiểm tra dữ liệu có sẵn trong WTForms để đảm bảo rằng địa chỉ email do người dùng nhập vào phù hợp với định dạng của địa chỉ email

Tiếp theo, chúng ta cũng sẽ lướt theo quy ước chung của các biểu mẫu đăng ký là yêu cầu người dùng nhập mật mã hai lần để tránh trạng thái nhập sai mật mã bên ngoài ý muốn. Vì vậy, chúng tôi sử dụng hai trường is_active9 và is_anonymous0. Trường is_anonymous0 cũng sử dụng một biến kiểm tra có sẵn gọi là is_anonymous2 để đảm bảo rằng giá trị đầu vào trường này phải giống như giá trị của trường is_active9 đã nhập trước đó

Và cuối cùng, chúng ta cũng có thêm hai hàm mới gọi là is_anonymous4 và is_anonymous5. Khi chúng ta thêm bất kỳ hàm nào với tên gọi theo mẫu is_anonymous6, WTForms sẽ hiểu các hàm này giống như các biến kiểm tra dữ liệu tùy biến (trình xác nhận tùy chỉnh) và sử dụng chúng cho các trường tương ứng sau khi sử dụng các hàm này. . Trong trường hợp này, chúng tôi sử dụng các chức năng kiểm tra dữ liệu này để đảm bảo rằng các giá trị tên người dùng và email mà người dùng nhập vào không tồn tại trong cơ sở dữ liệu, vì các truy vấn dữ liệu thay thế không được tìm thấy. . Nếu có kết quả trả về, các hàm này sẽ đưa ra một ngoại lệ is_anonymous7. Tham số cho các xác thực ngoại lệ là các thông báo lỗi tương ứng và sẽ được hiển thị bên cạnh các trường này khi dữ liệu nhập vào không chính xác

Để hiển thị biểu mẫu này, chúng ta cần xây dựng một mẫu HTML. Chúng ta sẽ đưa template này vào file app/templates/register. html. Chúng ta cũng viết mã cho mẫu này tương tự như cho mẫu đăng nhập

ứng dụng/mẫu/đăng ký. html. Mẫu cho biểu mẫu đăng ký người dùng

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

{% mở rộng "cơ sở. html" %}

 

{% chặn nội dung %}

    

Đăng ký

    

hành động="" method="post">

{{ hình thức. hidden_tag() }}

        

            {{ biểu mẫu. tên tài khoản. nhãn }}

            {{ biểu mẫu. tên người dùng(size=32) }}

{% cho lỗi trong biểu mẫu. tên tài khoản. lỗi %}

            kiểu="color. đỏ;">[{{ error }}]

{% endfor %}

        

        

            {{ biểu mẫu. e-mail. nhãn }}

            {{ biểu mẫu. email(size=64) }}

{% cho lỗi trong biểu mẫu. e-mail. lỗi %}

            kiểu="color. đỏ;">[{{ error }}]

{% endfor %}

        

        

            {{ biểu mẫu. mật khẩu mở khóa. nhãn }}

            {{ biểu mẫu. mật khẩu(size=32) }}

{% cho lỗi trong biểu mẫu. mật khẩu mở khóa. lỗi %}

            kiểu="color. đỏ;">[{{ error }}]

{% endfor %}

        

        

            {{ biểu mẫu. mật khẩu2. nhãn }}

            {{ biểu mẫu. mật khẩu2(size=32) }}

{% cho lỗi trong biểu mẫu. mật khẩu2. lỗi %}

            kiểu="color. đỏ;">[{{ error }}]

{% endfor %}

        

        

{{ biểu mẫu. gửi() }}

   

{% chặn kết thúc %}

Chúng ta cũng cần thêm liên kết từ trang đăng nhập đến trang đăng ký để người dùng mới có thể đăng ký với hệ thống như sau

ứng dụng/mẫu/đăng nhập. html. Liên kết đến trang đăng ký

1

    

Người dùng mới? . href="{{ url_for('register') }}">Click to Register!

Và cuối cùng, chúng ta cần viết hàm hiển thị cho trang đăng ký trong app/routes. py

ứng dụng/tuyến đường. py. Hàm hiển thị cho biểu mẫu đăng ký người dùng

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

từ ứng dụng nhập db

từ ứng dụng. biểu mẫu nhập Biểu mẫu đăng ký

 

.. .

 

@ứng dụng. tuyến đường('/register', methods=['GET', 'POST'])

def đăng ký().

    if current_user. is_authenticated.

        trả lại chuyển hướng(url_for('index'))

    biểu mẫu = Đơn đăng ký()

    nếu biểu mẫu. validate_on_submit().

        người dùng = Người dùng(username=form.tên người dùng. dữ liệu, email=biểu mẫu . .email. dữ liệu)

        người dùng. set_password(biểu mẫu. mật khẩu. dữ liệu)

        db. phiên. thêm(người dùng)

        db. phiên. cam kết()

        flash('Xin chúc mừng, bạn hiện là người dùng đã đăng ký. ')

        trả lại chuyển hướng(url_for('login'))

    return render_template('register. html', tiêu đề='Đăng ký', form=form)

Trong hàm này, chúng ta làm một số công việc theo tuần tự như sau. đảm bảo rằng những người dùng đã đăng ký không thể truy cập trang này (cách xử lý tương tự như khi một người dùng đã đăng nhập tìm cách truy cập trang đã đăng nhập). Tiếp theo, chúng ta sẽ kiểm tra các dữ liệu đã đăng ký có hợp lệ hay không, nếu không có lỗi (được xác nhận thông qua điều kiện is_anonymous8), chúng ta sẽ tạo một người dùng mới với các giá trị của tên người dùng, email và mật khẩu

Mã đăng nhập python

Với những thay đổi này, người dùng sẽ có thể tạo tài khoản người dùng, đăng nhập và đăng xuất. Hãy thử tất cả các vấn đề có lỗi để hiểu cách làm việc của mã kiểm tra lỗi mà chúng ta đã thêm vào chương trình. Chúng ta sẽ quay lại với hệ thống xác nhận người dùng và chức năng bổ sung để người dùng có thể đặt lại mật mã trong trường hợp họ đã quên trong một bài viết sau. Nhưng bây giờ, chúng ta hãy chuyển sang phần khác của ứng dụng