Las SPA no se beneficiarían de PKCE. PKCE resuelve un problema diferente al que estás describiendo.
En primer lugar, para SPAs la mejor práctica actual es utilizar el flujo implícito , no el flujo del código de autorización. Con el En el flujo implícito, el token de acceso se incluye en el fragmento de hash (#) del URI de redireccionamiento en lugar de en un componente de consulta (?). Como el navegador nunca incluye la parte del fragmento de hash de un URI cuando realiza una solicitud, el token no aparece en historial del navegador , los registros web ...
Cuando se trata de aplicaciones nativas , rfc8252 sección 6 dice que siguiente:
Los clientes de aplicaciones nativas públicas DEBEN implementar la clave de prueba para el intercambio de código (PKCE RFC7636])
En una nota al margen, observe que el requisito de PKCE es para clientes nativos públicos . Quizás se esté preguntando cómo puede ser posible que una aplicación nativa no sea pública. La respuesta se encuentra en sección 8.4 :
Excepto cuando se utiliza un mecanismo como el Registro dinámico de clientes [RFC7591] para proporcionar secretos por instancia, las aplicaciones nativas se clasifican como clientes públicos
No estoy exactamente seguro de cómo referirme a estos clientes ya que nunca he visto a cliente nativo confidencial mencionado en ninguna parte. Tal vez cliente nativo no público funcione :)
Para responder a su pregunta: ¿por qué se requiere el flujo de código de autorización con PKCE para las aplicaciones públicas nativas y no para las SPA?
La lógica es la siguiente:
- Uno de los propósitos principales de OAuth2 es evitar la exposición de las credenciales de los usuarios a los clientes.
- Para que las aplicaciones nativas cumplan con este requisito, el usuario no debe ingresar credenciales en ningún lugar al que tenga acceso la aplicación nativa. Por lo tanto, se deben evitar las pantallas de inicio de sesión nativas y las vistas web.
- La solución es que las aplicaciones nativas inicien un agente de usuario externo (consulte rfc8252 apéndice B ) donde el usuario se autentificará con el servidor de autorización y autorizará la aplicación. Las aplicaciones nativas no tienen acceso al agente de usuario externo, por lo que las credenciales del usuario son seguras.
- Sin embargo, se ha introducido una nueva complicación que no existía con las SPA: ¿el agente de usuario externo ahora debe comunicar la respuesta del servidor de autorización a la aplicación nativa? La respuesta es la comunicación entre aplicaciones (consulte sección 5 y section 7 )
- Desafortunadamente, varios tipos de comunicación entre aplicaciones pueden ser interceptados por aplicaciones de terceros maliciosos. Con el flujo implícito, esto significa que el token de acceso podría ser robado por una aplicación maliciosa, lo que sería algo muy malo. Esta es una de las razones principales por las que el flujo implícito no se usa para aplicaciones nativas.
- Pero incluso si en su lugar se usa el flujo de código de autorización, la aplicación de terceros maliciosos todavía puede interceptar el código de autorización y usarlo para obtener un token de acceso, ya que no hay un secreto de cliente. Por lo tanto, parece inútil utilizar el flujo de código de autorización en lugar del flujo implícito para aplicaciones públicas nativas.
- Aquí es donde PKCE entra. PKCE hace que, incluso si una aplicación maliciosa intercepta un código de autorización, no podrá intercambiarlo por un token de acceso. Esto se logra al requerir que la entidad que solicita el token de acceso demuestre que es la misma entidad que solicitó el código de autorización en primer lugar.
Esperemos que ahora entiendas por qué:
- Las SPA no se beneficiarían de PKCE ya que con las SPA todo ocurre
dentro del navegador. PKCE solo es útil cuando hay comunicación entre aplicaciones.
- Las aplicaciones nativas públicas no deben usar el flujo implícito porque la comunicación entre aplicaciones a veces puede ser insegura.
- Las aplicaciones nativas públicas deben usar el flujo de código de autorización + PKCE
Aquí hay una buena publicación de blog que puede proporcionar más información:
enlace