def _generate_pkce_pair(self): """Generate code_verifier and code_challenge (S256).""" self.code_verifier = secrets.token_urlsafe(64)[:128] code_challenge = hashlib.sha256(self.code_verifier.encode()).digest() # Base64url encode without padding code_challenge = secrets.token_urlsafe(32) # simplified; use proper base64url # For correctness, implement: import base64 code_challenge = base64.urlsafe_b64encode( hashlib.sha256(self.code_verifier.encode()).digest() ).decode().rstrip("=") return code_challenge
def __init__(self, client_id, redirect_uri, scopes=None): self.client_id = client_id self.redirect_uri = redirect_uri self.scopes = scopes or ["openid", "profile", "invoice.read"] self.code_verifier = None self.state = None lexoffice.login
lexoffice’s strength is strict PKCE enforcement and well‑structured OpenID Connect Discovery ( /.well-known/openid-configuration ). The lexoffice.login mechanism is a robust implementation of OAuth 2.0 + PKCE, suitable for both server‑side and public client applications. Developers must correctly generate the PKCE pair, validate the state parameter, and store tokens securely. By following the reference implementation and security recommendations in this paper, integration can achieve both usability and a high security level. use proper base64url # For correctness
import hashlib import secrets import requests from urllib.parse import urlencode, urlparse, parse_qs class LexofficeLogin: AUTH_URL = "https://login.lexoffice.io/connect/authorize" TOKEN_URL = "https://login.lexoffice.io/connect/token" validate the state parameter