Paano mai-secure ang isang Flask REST API na may JSON Web Token?

Alamin natin kung paano mai-secure ang isang REST API na may mga token ng web ng JSON upang maiwasan ang pag-abuso sa mga gumagamit at third-party na ito.


Kami ay magtatayo ng isang serbisyo ng database gamit SQLite at payagan ang mga gumagamit na ma-access ito sa pamamagitan ng isang REST API gamit ang mga pamamaraan ng HTTP tulad ng POST at PUT.

Bilang karagdagan, malalaman natin kung bakit ang mga token ng web ng JSON ay isang angkop na paraan upang maprotektahan ang pahinga ng API sa halip na digest at pangunahing pagpapatunay. Bago tayo magpatuloy, maunawaan natin ang termino ng mga web token ng JSON, REST API at Flask framework.

JSON Web Token

JSON web token, na kilala rin bilang JWT, ay ang ligtas na paraan ng paglilipat ng mga random na token sa pagitan ng dalawang partido o mga nilalang. Ang JSON ay karaniwang binubuo ng tatlong bahagi tulad ng mga sumusunod.

  • Payload
  • Header
  • Lagda

Gumagamit si JSON ng dalawang uri ng mga form ng istraktura kapag naglilipat ng data o impormasyon sa pagitan ng dalawang partido.

  • Serialized
  • Deserialized

Ginagamit ang serialized form kapag naglilipat ng data sa network sa pamamagitan ng bawat kahilingan at tugon habang ang deserialized form ay ginagamit kapag nagbabasa at sumulat ng data sa web token.

Sa serialized form, mayroong tatlong mga sangkap.

  • Header
  • Payload
  • Lagda

Ang sangkap ng header ay tumutukoy sa impormasyon ng cryptographic tungkol sa mga token. Halimbawa:

  • Nakapirmahan ba o hindi naka -ignign na JWT?
  • Tukuyin ang mga diskarte sa algorithm

Ang deserialized form, hindi katulad ng serialized form, ay naglalaman ng dalawang bahagi.

  • Payload
  • Header

REST API

Pinapayagan ng API (interface ng application programming) ang komunikasyon sa pagitan ng dalawang aplikasyon upang makuha o isumite ang data. Mayroong dalawang tanyag na uri ng mga API – web at system API.

Sa artikulong ito, titingnan lamang namin ang web API. Mayroong dalawang uri ng web API.

  • Humiling – Response API: Pahinga, GraphQL, Remote Procedure Call (RPC)
  • Kaganapan na Hinimok ng Kaganapan: WebHooks, Web Sockets, HTTP Streaming

Ang REST API ay nahuhulog sa ilalim ng kategorya ng kahilingan sa pagtugon. Ginagamit nito ang mga pamamaraan ng HTTP tulad ng GET, POST, at PUT upang maisagawa ang operasyon sa API.

Ang isang klasikong halimbawa ay kapag ang isang gumagamit ay nagpapadala ng isang pamamaraan ng GET sa serbisyo sa web upang humiling para sa o kumuha ng isang tukoy na mapagkukunan o isang koleksyon ng mga mapagkukunan. Pagkatapos ibabalik ng server ang tukoy na mapagkukunan o koleksyon ng mga mapagkukunan pabalik sa gumagamit na humiling nito.

Flask Framework

Ang Flask ay isang balangkas batay sa python. Ito ay isang micro-framework na ginagamit ng mga developer ng python upang makabuo ng pahinga ng API. Ito ay tinatawag na isang micro framework dahil pinahihintulutan nito ang mga developer, upang magdagdag ng pasadyang pagpapatotoo at anumang iba pang sistema ng backend batay sa mga kagustuhan.

Magsimula tayo sa pagpapatupad. Ang aking pag-setup ng system ay ang mga sumusunod.

  • Ubuntu bilang OS
  • Python 2.7+
  • Postman

Mag-set up ng isang virtual na kapaligiran gamit ang virtualenv

Kailangan nating mag-set up ng isang virtual na kapaligiran upang matiyak na ang ilang mga pakete ay hindi salungat sa mga pakete ng system. Gamitin natin ang virtualenv upang mag-set up ng isang bagong virtual na kapaligiran.

Sa pag-aakalang mayroon kang pip utos na magagamit sa iyong system, patakbuhin ang sumusunod na utos sa pamamagitan ng pip upang mai-install.

pip install ng virtualenv

Kung wala kang pip sa iyong makina, pagkatapos ay sundin ito dokumentasyon mag-install ng pip sa iyong system.

Susunod, lumikha ng isang direktoryo upang maiimbak o hawakan ang aming virtual na kapaligiran. Gamitin ang mkdir command na ipinakita sa ibaba upang lumikha ng isang direktoryo

mkdir flaskproject

Baguhin ang direktoryo ng flaskproject gamit ang sumusunod na utos

cd flaskproject

Sa loob ng direktoryo ng flaskproject, gumamit ng virtualenv tool upang lumikha ng isang virtual na kapaligiran tulad ng ipinapakita sa ibaba:

virtualenv flaskapi

Matapos mong magamit ang tool na virtualenv upang lumikha ng virtual na kapaligiran, patakbuhin ang utos ng cd upang mabago sa direktoryo ng flaskapi bilang virtual na kapaligiran at buhayin ito gamit ang utos sa ibaba.

pinagmulan bin / buhayin

Isagawa ang lahat ng mga gawain na may kaugnayan sa proyektong ito sa loob ng virtual na kapaligiran.

I-install ang mga pakete gamit ang pip

Ngayon na ang oras upang mag-install ng mga pakete tulad ng flask framework at PyJWT na gagamitin namin upang mabuo ang natitirang API at iba pang kinakailangang mga pakete para sa aming proyekto sa API.

Lumikha ng isang file ng requirements.txt kasama ang mga sumusunod na pakete.

Flask
pangmatagalan
uuid
Flask-SQLAlchemy
PyJWT

I-install ang mga ito sa pip.

pip install -r kinakailangan.txt

Mag-set up ng isang database

I-install ang SQLite.

apt-makakuha ng pag-install ng sqlite3

Lumikha ng isang database na pinangalanan ang library. Sa loob ng database na ito, gagawa kami ng dalawang talahanayan, lalo na ang talahanayan ng Mga Gumagamit at may-akda.

Ang talahanayan ng mga gumagamit ay maglalagay ng mga rehistradong gumagamit. Mga rehistradong gumagamit lamang ang maaaring magkaroon ng access sa talahanayan ng Mga May-akda.

Ang talahanayan ng mga may akda ay mag-iimbak ng impormasyon o mga detalye ng mga may-akda tulad ng pangalan ng may-akda, bansa ng kapanganakan at iba pa na isinumite ng mga rehistradong gumagamit.

Lumikha ng database gamit ang sumusunod na utos:

sqlite3 library.db

Maaari mong suriin kung matagumpay mong nilikha ang database sa pamamagitan ng paggamit ng utos sa ibaba:

.mga database

Magbukas ng isang bagong terminal at isagawa ang sumusunod sa virtual na kapaligiran na nilikha namin nang mas maaga.

hawakan ang app.py

I-paste ang sumusunod na code sa loob ng file na pinangalanan app.py

mula sa flask import Flask, kahilingan, pag-jsonify, gumawa_response
mula sa flask_sqlalchemy import SQLAlchemy
mula sa werkzeug.security import gener_password_hash, check_password_hash
pag-import uuid
import jwt
pag-import ng oras
mula sa mga function na i-import ang mga functiontools

Ang unang linya sa code sa itaas na nag-import ng mga pakete tulad ng kahilingan at jsonify. Gagamitin namin ang kahilingan upang subaybayan ang data ng antas ng kahilingan sa panahon ng isang kahilingan at gamitin ang jsonify sa mga tugon ng output sa a JSON format.

Sa susunod na linya, na-import namin ang SQLAlchemy mula sa flask_sqlalchemy upang maisama ang mga tampok ng SQLAlchemy sa flask.

Mula sa werkzeug.security, nag-import kami ng generate_password_hash upang makabuo ng password ng hash para sa mga gumagamit at check_password_hash upang suriin ang password ng gumagamit kapag inihahambing ang password na isinumite ng mga gumagamit gamit ang mga password ng gumagamit na nakaimbak sa database.

Sa wakas, nag-import kami ng uuid na kilala rin bilang unibersal na natatanging identifier upang makabuo ng mga random na numero ng id para sa mga gumagamit.

Pa rin, sa loob ng app.py file, ipatupad ang mga setting ng pagsasaayos para sa library ng API gamit ang code sa ibaba sa loob ng app.py file.

Ilagay ang sumusunod na code sa ilalim ng pahayag ng pag-import.

app = Flask (__ pangalan__)

app.config [‘SECRET_KEY’] = ‘Th1s1ss3cr3t’
app.config [‘SQLALCHEMY_DATABASE_URI’] = ‘sqlite: /////home/michael/geekdemos/geekapp/library.db’
app.config [‘SQLALCHEMY_TRACK_MODIFICATIONS’] = Tama

db = SQLAlchemy (app)

Ngayon lumikha ng dalawang mga modelo para sa talahanayan ng Mga Gumagamit at may-akda tulad ng ipinakita sa ibaba. Kopyahin at idikit ang code sa loob ng app.py file.

Ilagay ang code sa ibaba mismo sa ilalim ng setting ng database na ito db = SQLAlchemy (app)

Mga Gumagamit sa klase (db.Model):
id = db.Column (db.Integer, primary_key = Totoo)
public_id = db.Column (db.Integer)
pangalan = db.Column (db.String (50))
password = db.Column (db.String (50))
admin = db.Column (db.Boolean)
may-akda sa klase (db.Model):
id = db.Column (db.Integer, primary_key = Totoo)
pangalan = db.Column (db.String (50), natatangi = Totoo, nullable = Mali)
libro = db.Column (db.String (20), natatangi = Totoo, nullable = Mali)
bansa = db.Column (db.String (50), nullable = Mali)
booker_prize = db.Column (db.Boolean)

Bumuo ng Mga Tables ng Gumagamit at May-akda

Sa terminal, i-type ang sumusunod na code sa loob ng virtual na kapaligiran upang makabuo o lumikha ng mga talahanayan para sa parehong mga talahanayan ng Mga Gumagamit at May-akda tulad ng ipinakita sa ibaba

mula sa pag-import ng db
db.create_all ()

Pagkaraan, buksan ang file ng app.py sa loob ng virtual na kapaligiran at lumikha ng isa pang pag-andar.

Ang function na ito ay bubuo ng mga token upang payagan ang mga rehistradong gumagamit lamang na ma-access at magsagawa ng isang hanay ng mga operasyon ng API laban sa talahanayan ng Mga May-akda.

Ilagay ang code na ito sa ilalim ng modelo ng database para sa talahanayan ng Mga May-akda

def token_required (f):
@wraps (f)
def dekorador (* args, ** kwarg):

token = Wala

kung ‘x-access-tokens’ sa kahilingan.headers:
token = request.headers [‘x-access-tokens’]

kung hindi token:
bumalik jsonify ({‘message’: ‘nawawala ang isang wastong token’})

subukan:
data = jwt.decode (token, app.config [SECRET_KEY])
current_user = Users.query.filter_by (public_id = data [‘public_id’]) una ()
maliban sa:
bumalik jsonify ({‘message’: ‘hindi wasto ang token’})

bumalik f (kasalukuyang_user, * args, ** kwargs)
bumalik na dekorador

Lumikha ng mga ruta para sa talahanayan ng mga gumagamit

Ngayon lumikha ng isang ruta upang payagan ang mga gumagamit na magparehistro para sa may-akda API sa pamamagitan ng isang username at password tulad ng ipinapakita sa ibaba.

Muli buksan ang app.py file sa loob ng virtual na kapaligiran at i-paste ang sumusunod na code sa ilalim ng function token_required (f)

@ app.route (‘/ magparehistro’, mga pamamaraan = [‘GET’, ‘POST’])
def signup_user ():
data = request.get_json ()

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

new_user = Gumagamit (public_id = str (uuid.uuid4 ()), pangalan = data [‘pangalan’], password = hashed_password, admin = Mali
db.session.add (new_user)
db.session.commit ()

bumalik jsonify ({‘message’: ‘matagumpay na nakarehistro’})

Sa loob ng virtual na kapaligiran, lumikha ng isa pang ruta sa app.py file upang payagan ang mga rehistradong gumagamit na mag-login.

Kapag nag-log ang isang gumagamit, ang isang random na token ay nabuo para ma-access ng gumagamit ang API ng library.

I-paste ang code sa ibaba sa ilalim ng nakaraang ruta na nilikha namin.

@ app.route (‘/ pag-login’, mga pamamaraan = [‘GET’, ‘POST’])
def login_user ():

auth = request.authorization

kung hindi auth o hindi auth.username o hindi auth.password:
return make_response (‘hindi ma-verify’, 401, {‘WWW.Authentication’: ‘Pangunahing kaharian: "Kailangang mag-login"’})

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

kung check_password_hash (user.password, auth.password):
token = jwt.encode ({‘public_id’: user.public_id, ‘exp’: datetime.datetime.utcnow () + datetime.timedelta (minuto = 30)}, app.config [‘SECRET_KEY’])
bumalik jsonify ({‘token’: token.decode (‘UTF-8’)})

return make_response (‘hindi ma-verify’, 401, {‘WWW.Authentication’: ‘Pangunahing kaharian: "Kailangang mag-login"’})

Gayunpaman, sa loob ng virtual na kapaligiran, lumikha ng isa pang ruta sa app.py file upang makuha o makuha ang lahat ng mga rehistradong gumagamit.

Sinusuri ng code na ito ang lahat ng mga rehistradong gumagamit sa talahanayan ng Mga Gumagamit at ibabalik ang pangwakas na resulta sa isang format ng JSON.

I-paste ang code sa ibaba sa ilalim ng ruta ng pag-login

@ app.route (‘/ mga gumagamit’, mga pamamaraan = [‘GET’])
def get_all_users ():

mga gumagamit = Users.query.all ()

resulta = []

para sa gumagamit sa mga gumagamit:
user_data = {}
user_data [‘public_id’] = user.public_id
user_data [‘pangalan’] = user.name
user_data [‘password’] = user.password
user_data [‘admin’] = user.admin

resulta.append (user_data)

bumalik jsonify ({‘mga gumagamit’: resulta})

Lumikha ng mga ruta para sa talahanayan ng mga may-akda 

Lumikha ng mga ruta para sa talahanayan ng Mga May-akda upang mabigyan ng mga gumagamit ang lahat ng mga may-akda sa database, pati na rin tanggalin ang mga may-akda.

Ang mga gumagamit lamang na may wastong mga token ang maaaring magsagawa ng mga operasyon sa API.

Sa loob ng app.py file, lumikha ng isang ruta para sa mga rehistradong gumagamit upang lumikha ng mga bagong may-akda.

I-paste ang code na ito sa ilalim ng ruta na nagbibigay-daan sa isang gumagamit na makuha ang lahat ng mga rehistradong gumagamit.

@ app.route (‘/ may-akda’, mga pamamaraan = [‘POST’, ‘GET’])
@token_required
def create_author (kasalukuyang_user):

data = request.get_json ()

new_authors = May-akda (pangalan = data [‘pangalan’], bansa = data [‘bansa’], libro = data [‘book’], booker_prize = Totoo, user_id = current_user.id)
db.session.add (bagong_authors)
db.session.commit ()

bumalik jsonify ({‘message’: ‘nilikha ng bagong may-akda’})

Susunod, lumikha ng isa pang ruta upang payagan ang isang rehistradong gumagamit na may isang wastong token upang makuha ang lahat ng mga may-akda sa talahanayan ng Mga May-akda tulad ng ipinakita sa ibaba.

I-paste ang code na ito sa ibaba ng ruta na nagbibigay-daan sa isang gumagamit na lumikha ng isang bagong may-akda.

@ app.route (‘/ may-akda’, pamamaraan = [‘POST’, ‘GET’])
@token_required
def get_authors (kasalukuyang_user):

may-akda = may-akda.query.filter_by (user_id = current_user.id) .all ()

output = []
para sa may-akda sa mga may-akda:

author_data = {}
author_data [‘pangalan’] = author.name
author_data [‘libro’] = author.book
author_data [‘bansa’] = author.country
author_data [‘booker_prize’] = author.booker_prize
output.append (author_data)

bumalik jsonify ({‘list_of_authors’: output})

Sa wakas, nasa loob pa rin ng app.py file, lumikha ng isang ruta upang matanggal ang isang tinukoy na may-akda tulad ng ipinapakita sa ibaba.

I-paste ang code na ito sa ilalim ng ruta na nagbibigay-daan sa isang gumagamit na makuha ang isang listahan ng mga may-akda.

@ app.route (‘/ may-akda /’, mga pamamaraan = [‘DELETE’])
@token_required
def Delete_author (kasalukuyang_user, may-akda_id):
may-akda = Author.query.filter_by (id = author_id, user_id = current_user.id) .first ()
kung hindi may-akda:
bumalik jsonify ({‘message’: ‘wala ang may-akda’})

db.session.delete (may-akda)
db.session.commit ()

bumalik jsonify ({‘message’: ‘tinanggal ang may-akda’})

kung __name__ == ‘__main__’:
app.run (debug = Totoo)

Pagkaraan, i-save at isara ang file ng app.py sa loob ng virtual na kapaligiran.

Pagsubok sa API ng library kasama ang Postman

Sa seksyong ito, gagamitin namin ang isang tool ng postman upang magpadala ng isang kahilingan sa mga serbisyo sa database. Kung wala kang isang postman sa iyong makina, maaari mong malaman kung paano i-download at mai-install ito dito.

Bukod sa postman, maaari nating gamitin ang iba pang mga tool tulad ng Kulot upang magpadala ng mga kahilingan sa server.

Magbukas ng isang bagong terminal at i-type ang sumusunod:

postman

Ang command postman ay magiging sanhi ng iyong web browser na ipakita ang pahina sa ibaba:

postman_signup

Maaari kang magpasya na mag-sign up at lumikha ng isang libreng account ngunit laktawan namin at makakuha ng direktang pag-access sa app upang masubukan ang library ng API tulad ng ipinakita sa ibaba:

Subukan ang library api

Sa seksyong ito, papayagan namin ang isang gumagamit na magparehistro para sa API ng library sa pamamagitan ng pagbibigay ng isang username at isang natatanging password sa isang format ng JSON gamit ang paraan ng POST gamit ang mga hakbang sa ibaba:

  • Mag-click sa tab na may label na Katawan
  • Pagkatapos ay piliin ang raw button at piliin ang format ng JSON
  • magpasok ng isang username at password upang magrehistro tulad ng ipinapakita sa screenshot
  • Sa tabi ng pindutan ng padala, ipasok ang sumusunod na URL http://127.0.0.1/register
  • Sa wakas, baguhin ang pamamaraan sa POST at pindutin ang pindutan ng padala.

isang rehistro ng isang gumagamit para sa isang api

Ipapakita nito ang sumusunod na output tulad ng ipinakita sa ibaba:

Ngayon matagumpay nating nakarehistro ang isang gumagamit. Sige na hayaan ang gumagamit na nakarehistro lamang upang mag-login upang makabuo ng isang pansamantalang random na token upang ma-access ang talahanayan ng Mga May-akda gamit ang mga sumusunod na hakbang:

  •  Mag-click sa tab na pahintulot.
  • Sa ilalim ng seksyon ng uri, piliin ang pangunahing pagpapatunay.
  • Pagkatapos punan ang username at password form sa username at password na nakarehistro mo dati.
  • Sa wakas, pindutin ang pindutan ng padala upang mag-login at makabuo ng isang random na token.

Kapag matagumpay na ang pag-login ng gumagamit, ang isang random na token ay nabuo para sa gumagamit tulad ng ipinapakita sa screenshot.

Gagamitin namin ang nabuong random na token upang ma-access ang talahanayan ng Mga May-akda.

Sa seksyong ito, magdagdag kami ng impormasyon ng isang may-akda sa talahanayan ng Mga May-akda sa pamamagitan ng paraan ng POST gamit ang mga sumusunod na hakbang:

  • Mag-click sa tab ng header
  • Isama ang sumusunod na mga header ng HTTP na ipinakita sa screenshot

  • Susunod, mag-click sa tab ng katawan at ipasok ang mga detalye ng bagong may-akda
  • Pagkatapos ay pindutin ang pindutan ng padala upang magdagdag ng mga detalye ng may-akda sa talahanayan ng May-akda

Maaari mo ring makuha ang impormasyon ng mga may-akda sa talahanayan ng Mga May-akda sa pamamagitan ng sumusunod:

  • Tiyaking ang iyong nabuong token ay nasa seksyon ng header. kung wala ito, kailangan mong punan ito ng iyong token.
  • Sa tabi ng pindutan ng padala, ipasok ang URL na ito http://127.0.0.1/authors
  • Pagkatapos ay baguhin ang pamamaraan ng HTTP upang GET at pindutin ang pindutan ng pagpapadala upang makuha ang mga detalye ng mga may-akda.

Sa wakas, maaari mong tanggalin ang (mga) may-akda sa talahanayan ng Mga May-akda sa pamamagitan ng pamamaraang DELETE gamit ang mga sumusunod na hakbang:

  • Siguraduhin na ang iyong token ay nasa seksyon din ng header. Maaari mong suriin ang tab ng header upang matiyak na ang kinakailangang impormasyon ay nasa lugar.
  • Sa tabi ng pindutan ng padala, ipasok ang URL na ito http://127.0.0.1/sam
  • Pagkatapos pindutin ang pindutan ng padala upang tanggalin ang gumagamit na iyong tinukoy.

Maaari mong mahanap ang kumpletong mapagkukunan ng code sa Github.  Maaari mong i-clone ito at suriin ito sa iyong makina.

TAGS:

  • Python

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