Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

Python3の標準ライブラリのみでCGI その3:認証をつける

実際のところ

import http.server
import socketserver
import threading
import base64
import json

class ThreadedHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
    daemon_threads = True

class CGIHandler(http.server.CGIHTTPRequestHandler):
    cgi_directories = ["/"]  # CGIスクリプトを配置するディレクトリ

    # ユーザ名とパスワードをファイルから読み込む
    with open('loginInfo.json') as f:
        login_info = json.load(f)
    USERNAME = login_info['username']
    PASSWORD = login_info['password']

    def do_AUTHHEAD(self):
        self.send_response(401)
        self.send_header('WWW-Authenticate', 'Basic realm=\"Authentication required\"')
        self.send_header('Content-type', 'text/html')
        self.end_headers()

    def authenticate(self):
        if self.headers.get('Authorization') is None:
            self.do_AUTHHEAD()
            self.wfile.write(bytes('no auth header received', 'utf-8'))
            pass
        elif self.headers.get('Authorization') == 'Basic ' + base64.b64encode(f'{self.USERNAME}:{self.PASSWORD}'.encode('utf-8')).decode('utf-8'):
            return True
        else:
            self.do_AUTHHEAD()
            self.wfile.write(bytes('not authenticated', 'utf-8'))

    def do_GET(self):
        if not self.authenticate():
            return
        super().do_GET()

    def do_POST(self):
        if not self.authenticate():
            return
        super().do_POST()

with ThreadedHTTPServer(("", 8000), CGIHandler) as httpd:
    print("serving at port", 8000)
    httpd.serve_forever()