Làm cách nào để bảo mật API REST Flask bằng mã thông báo web JSON?

Hãy cùng tìm hiểu cách bảo mật API REST bằng mã thông báo web JSON để ngăn người dùng và ứng dụng của bên thứ ba lạm dụng nó.


Chúng tôi sẽ xây dựng một dịch vụ cơ sở dữ liệu bằng cách sử dụng SQLite và cho phép người dùng truy cập nó thông qua API REST bằng các phương thức HTTP như POST và PUT.

Ngoài ra, chúng ta sẽ biết lý do tại sao mã thông báo web JSON là một cách phù hợp để bảo vệ API còn lại thay vì xác thực và xác thực cơ bản. Trước khi chúng tôi tiếp tục, hãy để cho tôi hiểu thuật ngữ mã thông báo web JSON, khung API REST và Flask.

Mã thông báo web JSON

Mã thông báo web JSON, còn được gọi là JWT, là cách an toàn để chuyển mã thông báo ngẫu nhiên giữa hai bên hoặc thực thể. JSON thường được tạo thành từ ba phần như sau.

  • Khối hàng
  • Tiêu đề
  • Chữ ký

JSON sử dụng hai loại biểu mẫu cấu trúc khi truyền dữ liệu hoặc thông tin giữa hai bên.

  • Nối tiếp
  • Tuyệt vọng

Biểu mẫu được tuần tự hóa được sử dụng khi truyền dữ liệu vào mạng thông qua từng yêu cầu và phản hồi trong khi hình thức giải tuần tự được sử dụng khi đọc và ghi dữ liệu vào mã thông báo web.

Ở dạng nối tiếp, có ba thành phần.

  • Tiêu đề
  • Khối hàng
  • Chữ ký

Thành phần tiêu đề xác định thông tin mật mã về mã thông báo. Ví dụ:

  • Được ký hay chưa ký JWT?
  • Xác định các kỹ thuật thuật toán

Biểu mẫu khử lưu huỳnh, không giống như biểu mẫu nối tiếp, chứa hai thành phần.

  • Khối hàng
  • Tiêu đề

API REST

API (giao diện lập trình ứng dụng) cho phép giao tiếp giữa hai ứng dụng để lấy hoặc gửi dữ liệu. Có hai loại API phổ biến – API web và hệ thống.

Trong bài viết này, chúng tôi sẽ chỉ xem xét API web. Có hai loại API web.

  • Yêu cầu – API phản hồi: Nghỉ ngơi, GraphQL, Cuộc gọi thủ tục từ xa (RPC)
  • API hướng sự kiện: WebHooks, Web Sockets, HTTP Streaming

API REST thuộc danh mục yêu cầu đáp ứng. Nó sử dụng các phương thức HTTP như GET, POST và PUT để thực hiện các hoạt động API.

Một ví dụ kinh điển là khi người dùng gửi phương thức GET đến dịch vụ web để yêu cầu hoặc lấy một tài nguyên cụ thể hoặc một bộ sưu tập tài nguyên. Sau đó, máy chủ sẽ gửi lại tài nguyên cụ thể hoặc bộ sưu tập tài nguyên cho người dùng đã yêu cầu.

Khung bình

Flask là một khung dựa trên python. Nó là một khung vi mô được các nhà phát triển python sử dụng để xây dựng API còn lại. Nó được gọi là khung vi mô vì nó cho phép các nhà phát triển, ví dụ, thêm xác thực tùy chỉnh và bất kỳ hệ thống phụ trợ nào khác dựa trên tùy chọn.

Hãy để chúng tôi bắt đầu với việc thực hiện. Thiết lập hệ thống của tôi như sau.

  • Ubuntu là hệ điều hành
  • Python 2.7+
  • Người phát thơ

Thiết lập môi trường ảo bằng virtualenv

Chúng ta cần thiết lập một môi trường ảo để đảm bảo rằng một số gói sẽ không xung đột với các gói hệ thống. Hãy để sử dụng virtualenv để thiết lập một môi trường ảo mới.

Giả sử bạn có sẵn lệnh pip trên hệ thống của mình, hãy chạy lệnh sau qua pip để cài đặt.

Pip cài đặt virtualenv

Nếu bạn không có pip trên máy của bạn, thì hãy làm theo tài liệu để cài đặt pip trên hệ thống của bạn.

Tiếp theo, hãy để cùng nhau tạo một thư mục để lưu trữ hoặc giữ môi trường ảo của chúng tôi. Sử dụng lệnh mkdir hiển thị bên dưới để tạo một thư mục

mkdir jarproject

Thay đổi vào thư mục jarproject bằng lệnh sau

cd jarproject

Trong thư mục jarproject, sử dụng công cụ virtualenv để tạo môi trường ảo như dưới đây:

virtualenv jarapi

Sau khi bạn đã sử dụng công cụ virtualenv để tạo môi trường ảo, hãy chạy lệnh cd để thay đổi vào thư mục jarapi dưới dạng môi trường ảo và kích hoạt nó bằng lệnh bên dưới.

thùng nguồn / kích hoạt

Thực hiện tất cả các nhiệm vụ liên quan đến dự án này trong môi trường ảo.

Cài đặt gói bằng pip

Bây giờ đã đến lúc cài đặt các gói như khung bình và PyJWT mà chúng ta sẽ sử dụng để xây dựng API còn lại và các gói cần thiết khác cho dự án API của chúng tôi.

Tạo một tệp tests.txt với các gói sau.

Bình giữ nhiệt
ngày giờ
uuid
Flask-SQLAlchemy
Kim tự tháp

Cài đặt chúng với pip.

cài đặt pip -r tests.txt

Thiết lập cơ sở dữ liệu

Hãy cài đặt SQLite SQLite.

apt-get cài đặt sqlite3

Tạo một cơ sở dữ liệu có tên là thư viện. Bên trong cơ sở dữ liệu này, chúng tôi sẽ tạo hai bảng, đó là bảng Người dùng và Tác giả.

Bảng người dùng sẽ chứa người dùng đã đăng ký. Chỉ người dùng đã đăng ký mới có thể có quyền truy cập vào bảng Tác giả.

Bảng tác giả sẽ lưu trữ thông tin hoặc thông tin chi tiết của tác giả như tên của tác giả, quốc gia khai sinh, v.v..

Tạo cơ sở dữ liệu bằng lệnh sau:

thư viện sqlite3.db

Bạn có thể kiểm tra xem bạn đã tạo thành công cơ sở dữ liệu chưa bằng cách sử dụng lệnh bên dưới:

.cơ sở dữ liệu

Mở một thiết bị đầu cuối mới và thực hiện các thao tác sau trong môi trường ảo mà chúng ta đã tạo trước đó.

chạm vào ứng dụng

Dán đoạn mã sau vào tệp có tên app.py

từ bình nhập khẩu bình, yêu cầu, jsonify, make_response
từ jar_sqlalchemy nhập SQLAlchemy
từ werkzeug.security nhập tạo_password_hash, check_password_hash
nhập khẩu uuid
nhập khẩu
nhập thời gian
từ kết thúc nhập khẩu funcools

Dòng đầu tiên trong mã trên các gói nhập khẩu như request và jsonify. Chúng tôi sẽ sử dụng yêu cầu để theo dõi dữ liệu cấp yêu cầu trong khi yêu cầu và sử dụng jsonify để trả lời đầu ra trong một JSON định dạng.

Trên dòng tiếp theo, chúng tôi đã nhập SQLAlchemy từ jar_sqlalchemy để tích hợp các tính năng SQLAlchemy vào trong bình.

Từ werkzeug.security, chúng tôi đã nhập Gener_password_hash để tạo mật khẩu băm cho người dùng và check_password_hash để kiểm tra mật khẩu của người dùng khi so sánh mật khẩu được gửi bởi người dùng với mật khẩu của người dùng được lưu trữ trong cơ sở dữ liệu.

Cuối cùng, chúng tôi đã nhập uuid còn được gọi là số nhận dạng duy nhất phổ quát để tạo số id ngẫu nhiên cho người dùng.

Tuy nhiên, bên trong tệp app.py, hãy triển khai cài đặt cấu hình cho API thư viện bằng mã bên dưới trong tệp app.py.

Đặt mã sau bên dưới câu lệnh nhập.

ứng dụng = Bình (__ tên__)

app.config [‘SECRET_KEY’] = ‘Th1s1ss3cr3t’
app.config [‘SQLALCHEMY_DATABASE_URI’] = ‘sqlite: /////home/michael/geekdemos/geekapp/l Library.db’
app.config [‘SQLALCHEMY_TRACK_MODIFICATION’] = Đúng

db = SQLAlchemy (ứng dụng)

Bây giờ tạo hai mô hình cho bảng Người dùng và Tác giả như dưới đây. Sao chép và dán mã bên trong tệp app.py.

Đặt mã bên dưới ngay bên dưới cơ sở dữ liệu này cài đặt db = SQLAlchemy (ứng dụng)

người dùng lớp (db.Model):
id = db.Column (db.Integer, chính_key = True)
công khai_id = db.Column (db.Integer)
tên = db.Column (db.String (50))
mật khẩu = db.Column (db.String (50))
quản trị = db.Column (db.Boolean)
lớp Tác giả (db.Model):
id = db.Column (db.Integer, chính_key = True)
name = db.Column (db.String (50), unique = True, nullable = Sai))
book = db.Column (db.String (20), unique = True, nullable = Sai))
country = db.Column (db.String (50), nullable = Sai))
booker_prize = db.Column (db.Boolean)

Tạo bảng người dùng và tác giả

Trên thiết bị đầu cuối, nhập mã sau vào bên trong môi trường ảo để tạo hoặc tạo bảng cho cả bảng Người dùng và Tác giả như được hiển thị bên dưới

từ db nhập ứng dụng
db.create_all ()

Sau đó, mở tệp app.py bên trong môi trường ảo và tạo một chức năng khác.

Hàm này sẽ tạo mã thông báo để chỉ cho phép người dùng đã đăng ký truy cập và thực hiện một tập hợp các hoạt động API đối với bảng Tác giả.

Đặt mã này bên dưới mô hình cơ sở dữ liệu cho bảng Tác giả

def token_Vquired (f):
@wraps (f)
def decorator (* args, ** kwargs):

mã thông báo = Không có

if ‘x-access-tokens’ trong request.headers:
mã thông báo = request.headers [‘x-access-tokens’]

nếu không mã thông báo:
return jsonify ({‘message’: ‘thiếu mã thông báo hợp lệ’})

thử:
data = jwt.decode (mã thông báo, app.config [SECRET_KEY])
current_user = Users.query.filter_by (public_id = data [‘public_id’]). first ()
ngoại trừ:
return jsonify ({‘message’: ‘mã thông báo không hợp lệ’})

trả về f (current_user, * args, ** kwargs)
trang trí trở lại

Tạo tuyến đường cho bảng người dùng

Bây giờ, hãy để LÊ tạo một tuyến đường để cho phép người dùng đăng ký API tác giả thông qua tên người dùng và mật khẩu như được hiển thị bên dưới.

Một lần nữa mở tệp app.py bên trong môi trường ảo và dán đoạn mã sau bên dưới hàm token_Vquired (f)

@ app.route (‘/ đăng ký’, phương thức = [‘NHẬN’, ‘POST’])
def đăng nhập_user ():
dữ liệu = request.get_json ()

hashed_password = created_password_hash (data [‘password’], method = ‘sha256’)

new_user = Users (public_id = str (uuid.uuid4 ()), name = data [‘name’], password = hashed_password, admin = false)
db.session.add (new_user)
db.session.commit ()

return jsonify ({‘message’: ‘đã đăng ký thành công’})

Trong môi trường ảo, tạo một tuyến đường khác trong tệp app.py để cho phép người dùng đã đăng ký đăng nhập.

Khi người dùng đăng nhập, mã thông báo ngẫu nhiên được tạo để người dùng truy cập API thư viện.

Dán mã bên dưới bên dưới tuyến đường trước mà chúng tôi đã tạo.

@ app.route (‘/ đăng nhập’, phương thức = [‘GET’, ‘POST’])
def login_user ():

auth = request. Authorization

nếu không auth hoặc không auth.username hoặc không auth.password:
return make_response (‘không thể xác minh’, 401, {‘WWW.Authentication’: ‘Cõi cơ bản: "yêu cầu đăng nhập"’})

user = Users.query.filter_by (name = auth.username) .first ()

if check_password_hash (user.password, auth.password):
token = jwt.encode ({‘công khai_id
return jsonify ({‘mã thông báo’: token.decode (‘UTF-8’)})

return make_response (‘không thể xác minh’, 401, {‘WWW.Authentication’: ‘Cõi cơ bản: "yêu cầu đăng nhập"’})

Tuy nhiên, trong môi trường ảo, hãy tạo một tuyến đường khác trong tệp app.py để nhận hoặc truy xuất tất cả người dùng đã đăng ký.

Mã này kiểm tra tất cả người dùng đã đăng ký trong bảng Người dùng và trả về kết quả cuối cùng ở định dạng JSON.

Dán mã bên dưới tuyến đường đăng nhập

@ app.route (‘/ users’, phương thức = [‘GET’])
def get_all_users ():

users = Users.query.all ()

kết quả = []

cho người dùng trong người dùng:
user_data = {}
user_data [‘public_id’] = user.public_id
user_data [‘name’] = user.name
user_data [‘password’] = user.password
user_data [‘admin’] = user.admin

result.append (user_data)

return jsonify ({‘users’: result})

Tạo tuyến đường cho bảng tác giả 

Hãy để lòng đường tạo cho bảng Tác giả để cho phép người dùng truy xuất tất cả các tác giả trong cơ sở dữ liệu, cũng như xóa các tác giả.

Chỉ người dùng có mã thông báo hợp lệ mới có thể thực hiện các hoạt động API này.

Bên trong tệp app.py, tạo tuyến đường cho người dùng đã đăng ký để tạo tác giả mới.

Dán mã này bên dưới tuyến đường cho phép người dùng truy xuất tất cả người dùng đã đăng ký.

@ app.route (‘/ tác giả’, phương thức = [‘POST’, ‘GET’])
@token_Vquired
def tạo_ Tác giả (current_user):

dữ liệu = request.get_json ()

new_authors = Tác giả (name = data [‘name’], country = data [‘country’], book = data [‘book’], booker_prize = True, user_id = current_user.id)
db.session.add (new_authors)
db.session.commit ()

return jsonify ({‘message’: ‘tác giả mới được tạo’})

Tiếp theo, tạo một tuyến đường khác để cho phép người dùng đã đăng ký có mã thông báo hợp lệ truy xuất tất cả các tác giả trong bảng Tác giả như dưới đây.

Dán mã này bên dưới tuyến đường cho phép người dùng tạo tác giả mới.

@ app.route (‘/ tác giả’, phương thức = [‘POST’, ‘GET’])
@token_Vquired
def get_authors (current_user):

tác giả = Aut Tác.query.filter_by (user_id = current_user.id) .all ()

đầu ra = []
cho tác giả trong các tác giả:

tác giả_data = {}
Author_data [‘name’] = Author.name
Author_data [‘book’] = Author.book
Author_data [‘country’] = Author.country
Author_data [‘booker_prize’] = tác giả.booker_prize
đầu ra.append (tác giả_data)

return jsonify ({‘list_of_authors’: output})

Cuối cùng, vẫn bên trong tệp app.py, tạo tuyến đường để xóa một tác giả được chỉ định như hiển thị bên dưới.

Dán mã này bên dưới tuyến đường cho phép người dùng truy xuất danh sách tác giả.

@ app.route (‘/ tác giả /’, phương thức = [‘XÓA’])
@token_Vquired
def xóa_ Tác giả (current_user, Author_id):
tác giả = Author.query.filter_by (id = Author_id, user_id = current_user.id) .first ()
nếu không phải tác giả:
return jsonify ({‘message’: ‘tác giả không tồn tại’})

db.session.delete (tác giả)
db.session.commit ()

return jsonify ({‘message’: ‘Đã xóa tác giả’})

if __name__ == ‘__main__’:
app.run (gỡ lỗi = Đúng)

Sau đó, lưu và đóng tệp app.py trong môi trường ảo.

Kiểm tra API thư viện với Postman

Trong phần này, chúng tôi sẽ sử dụng một công cụ đưa thư để gửi yêu cầu đến các dịch vụ cơ sở dữ liệu. Nếu bạn không có một người đưa thư trên máy của mình, bạn có thể tìm hiểu cách tải xuống và cài đặt nó đây.

Ngoài người đưa thư, chúng tôi có thể sử dụng các công cụ khác như Xoăn gửi yêu cầu đến máy chủ.

Mở một thiết bị đầu cuối mới và gõ như sau:

người phát thơ

Người đưa thư lệnh sẽ khiến trình duyệt web của bạn hiển thị trang bên dưới:

postman_signup

Bạn có thể quyết định đăng ký và tạo một tài khoản miễn phí nhưng chúng tôi sẽ bỏ qua và truy cập trực tiếp vào ứng dụng để kiểm tra API thư viện như dưới đây:

Kiểm tra thư viện api

Trong phần này, chúng tôi sẽ cho phép người dùng đăng ký API thư viện bằng cách cung cấp tên người dùng và mật khẩu duy nhất ở định dạng JSON bằng phương thức POST bằng các bước bên dưới:

  • Nhấp vào tab có nhãn Body
  • Sau đó chọn nút thô và chọn định dạng JSON
  • nhập tên người dùng và mật khẩu để đăng ký như trong ảnh chụp màn hình
  • Bên cạnh nút gửi, hãy chèn URL sau http://127.0.0.1/register
  • Cuối cùng, thay đổi phương thức thành POST và nhấn nút gửi.

một người dùng đăng ký cho một api

Nó sẽ hiển thị đầu ra sau đây như hình dưới đây:

Bây giờ chúng tôi đã đăng ký thành công một người dùng. Hãy để đi trước để cho phép người dùng vừa đăng ký đăng nhập để tạo mã thông báo ngẫu nhiên tạm thời để truy cập vào bảng Tác giả bằng các bước sau:

  •  Nhấp vào tab ủy quyền.
  • Trong phần loại, chọn xác thực cơ bản.
  • Sau đó điền vào tên người dùng và mật khẩu với tên người dùng và mật khẩu bạn đã đăng ký trước đó.
  • Cuối cùng, nhấn nút gửi để đăng nhập và tạo mã thông báo ngẫu nhiên.

Khi người dùng đăng nhập thành công, mã thông báo ngẫu nhiên được tạo cho người dùng như trong ảnh chụp màn hình.

Chúng tôi sẽ sử dụng mã thông báo ngẫu nhiên được tạo để truy cập vào bảng Tác giả.

Trong phần này, chúng tôi sẽ thêm thông tin của tác giả vào bảng Tác giả thông qua phương thức POST bằng các bước sau:

  • Nhấp vào tab tiêu đề
  • Bao gồm các tiêu đề HTTP sau được hiển thị trong ảnh chụp màn hình

  • Tiếp theo, nhấp vào tab cơ thể và nhập chi tiết của tác giả mới
  • Sau đó nhấn nút gửi để thêm chi tiết tác giả vào bảng Tác giả

Bạn cũng có thể truy xuất thông tin của tác giả trong bảng Tác giả thông qua các mục sau:

  • Đảm bảo mã thông báo được tạo của bạn nằm trong phần tiêu đề. nếu nó không ở đó, bạn cần điền nó vào mã thông báo của bạn.
  • Bên cạnh nút gửi, hãy nhập URL này http://127.0.0.1/authors
  • Sau đó thay đổi phương thức HTTP thành GET và nhấn nút gửi để lấy thông tin chi tiết về tác giả.

Cuối cùng, bạn có thể xóa (các) tác giả trong bảng Tác giả thông qua phương thức XÓA bằng các bước sau:

  • Đảm bảo mã thông báo của bạn vẫn nằm trong phần tiêu đề. Bạn có thể kiểm tra tab tiêu đề để đảm bảo có thông tin cần thiết.
  • Bên cạnh nút gửi, nhập URL này http://127.0.0.1/sam
  • Sau đó nhấn nút gửi để xóa người dùng bạn đã chỉ định.

Bạn có thể tìm thấy mã nguồn hoàn chỉnh trên Github.  Bạn có thể sao chép nó và kiểm tra nó trên máy của bạn.

THẺ

  • Con trăn

Jeffrey Wilson Administrator
Sorry! The Author has not filled his profile.
follow me
    Like this post? Please share to your friends:
    Adblock
    detector
    map