服務器偵聽資料包,我們將 http GET 請求資料包發送到此偵聽器。如果我們使用帶有用戶名/密碼的 auth 標頭,服務器不接受連接并且失敗。有沒有辦法在偵聽器上決議此 auth 標頭資訊(用戶名/密碼) ? 因為我們要根據用戶/通行證比較進行認證
注意:在 GET 資料包 http 偵聽器中沒有 auth 標頭接受連接并且它作業正常
HTTP 資料包偵聽器
import socket
serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 8080
serverSocket.bind(("127.0.0.1", serverPort))
serverSocket.listen(1)
while True:
print('Ready to serve...')
try :
connectionSocket, addr = serverSocket.accept()
except :
print (f"Socket error occured for 127.0.0.1 {serverPort} ")
客戶端
import requests
from requests.auth import HTTPBasicAuth
r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'pass'))
感謝您的幫助!
uj5u.com熱心網友回復:
這是您需要的作業示例。
tl; dr:正如評論中指出的那樣,使用套接字您正在傳輸級別作業。HTTP 基本身份驗證位于 TCP/IP(或 OSI)堆疊中的更高級別。如果您不想接受 HTTP 協議(??是嗎?),您需要手動處理請求和標頭,模仿 HTTP 協議。實際上,pythonrequests管理成熟的 HTTP 請求。
我稍微修改了您的代碼以決議 http 標頭并管理類似 HTTP 的身份驗證。好了(代碼中的注釋和解釋):
import socket, base64
from http.server import BaseHTTPRequestHandler
from io import BytesIO
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverPort = 8080
serverSocket.bind(("127.0.0.1", serverPort))
serverSocket.listen(1)
# Auth section
user = 'user'
password = 'pass'
# The token you want the client to provide (string)
server_token = base64.b64encode(bytes(f'{user}:{password}','utf-8')).decode('utf-8')
# Use this simple class to parse you HTTP headers
# Read more here: https://stackoverflow.com/a/5955949/4820341
class HTTPRequest(BaseHTTPRequestHandler):
def __init__(self, request_text):
self.rfile = BytesIO(request_text)
self.raw_requestline = self.rfile.readline()
self.error_code = self.error_message = None
self.parse_request()
def send_error(self, code, message):
self.error_code = code
self.error_message = message
while True:
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
data = connectionSocket.recv(1024)
# Those are your data coming from the client
print(data.decode('utf-8'))
# parse your headers
http_headers = HTTPRequest(data)
try:
# get the incoming auth token
client_token = http_headers.headers['Authorization'].strip('Basic ')
if server_token != client_token:
connectionSocket.sendall(bytes("HTTP/1.1 401 Unauthorized\n\n" 'Wrong credetials', 'utf-8'))
else:
# process the request and do your stuff here
connectionSocket.sendall(bytes("HTTP/1.1 200 OK\n\n" 'Ok, all is fine here', 'utf-8'))
except AttributeError:
connectionSocket.sendall(bytes("HTTP/1.1 401 Unauthorized\n\n" 'No credentials provided', 'utf-8'))
finally:
connectionSocket.close()
下面是requests.getwith auth 看起來像服務器端的樣子:
Ready to serve...
GET / HTTP/1.1
Host: 127.0.0.1:8080
User-Agent: python-requests/2.26.0
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Authorization: Basic dXNlcjpwYXNz
現在,讓我們看看它的實際效果:
>>> r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'pass'))
>>> r.status_code
200
>>> r.text
'Ok, all is fine here'
>>>
>>>
>>> r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'wrongpass'))
>>> r.status_code
401
>>> r.text
'wrong credentials'
>>>
>>>
>>> r = requests.get('http://127.0.0.1:8080')
>>> r.status_code
401
>>> r.text
'No credentials provided'
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/356280.html
