http授权如何确认user/pass?

How to confirm user/pass for http authorization?

服务器侦听数据包,我们向此发送 http GET 请求数据包 listener.If 我们使用 auth header 和 username/pass 服务器不接受连接,它 fails.Is 那里有什么方法可以在侦听器上解析此 auth header 信息 (username/pass)?因为我们要根据user/pass比较

进行认证

注意:在 GET 数据包中没有身份验证 header HTTP 侦听器接受连接并且它工作正常

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} ")

HTTP 客户端

import requests
from requests.auth import HTTPBasicAuth

r = requests.get('http://127.0.0.1:8080',auth = HTTPBasicAuth('user', 'pass'))

感谢您的帮助!

这是您需要的工作示例。

tl;dr:正如评论中所指出的那样,您在传输级别使用套接字。 HTTP Basic Auth 位于 TCP/IP(或 OSI)堆栈的较高级别。如果您不想接受 HTTP 协议(​​是吗?),您需要手动处理请求和 headers,模仿 HTTP 协议。实际上,python requests 管理 full-fledged HTTP 请求。

我稍微修改了您的代码以解析 http headers 并管理 HTTP-like 身份验证。好了(代码中的注释和解释):

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://whosebug.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.get 身份验证看起来像这样:

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'