: Enable logging on the token exchange but redact code_verifier and refresh_token before persisting. 7. Comparison with Other Accounting APIs | Feature | lexoffice | DATEV | Xero | QuickBooks | |---------|-----------|-------|------|-------------| | OAuth2 | ✅ PKCE | ✅ PKCE | ✅ PKCE | ✅ PKCE | | Refresh token rotation | ✅ (recommended) | ❌ | ✅ | ✅ | | Sandbox environment | ✅ | ✅ | ✅ | ✅ | | Scope discovery via metadata | ✅ OIDC Discovery | ❌ | ✅ | ✅ |
def handle_callback(self, callback_url): """Parse callback, verify state, exchange code for tokens.""" parsed = urlparse(callback_url) query = parse_qs(parsed.query) if "state" not in query or query["state"][0] != self.state: raise ValueError("Invalid state parameter – possible CSRF attack") if "code" not in query: raise ValueError("No authorization code received") auth_code = query["code"][0] lexoffice.login
Future work could explore automated refresh token handling and background token refresh in SPAs using Web Workers. The principles outlined here are transferable to any OAuth2‑protected financial API. [1] lexoffice API Documentation. Authentication . Retrieved from https://developers.lexoffice.io/docs/#authentication [2] IETF RFC 6749 – The OAuth 2.0 Authorization Framework. [3] IETF RFC 7636 – Proof Key for Code Exchange (PKCE). [4] OWASP. OAuth 2.0 Security Cheat Sheet . [5] lexoffice OpenID Configuration – https://login.lexoffice.io/.well-known/openid-configuration Appendix – Full Token Response Example : Enable logging on the token exchange but