A clear walkthrough. It is worth adding PKCE even for confidential clients, since OAuth 2.1 makes it the default and it protects against authorization code interception at almost no cost. Validating the state parameter against a value bound to the user's session is the other step people skip, and it is what actually stops login CSRF.