É super importante que você leia a documentação oficial (tópico referencia no artigo OAuth) falando sobre OAuth 2.0 e PKCE, para entender de forma aprofundada, mas vou dar um resumo super abreviado sobre o que é PKCE e como implementar.
É um par de chaves que são geradas a cada interação de login, para garantir que o cliente que está tentando requisitar o token de acesso seja o mesmo que gerou o código para requisitar o token de acesso, ou seja, uma mitigação para uma vulnerabilidade de comunicação.
No momento de cadastrar sua aplicação como client
em nosso sitema, vamos sempre habilitar o PKCE, com uma exceção que é para um client
que possui comunicação somente via frontend, e para esses casos mitigamos utilizando configurações de CORS, que não vamos falar aqui, mas é legal compartilhar a existência dessas possibilidades.
Você já viu que o processo de handshake possue 2 etapas básicas, a primeira é requisitar autenticação do usuário no provedor, e a segunda é requisitar o token de acesso deste usuário em sua aplicação. Em cada uma delas, você deve enviar, entre outros campos, uma chave de segurança, como no desenho abaixo:
O código abaixo foi escrito na linguagem C# como exemplo.
using System.Security.Cryptography;
public static string ConvertInvalidWebCharacters(this string content)
=> content.TrimEnd('=').Replace('+', '-').Replace('/', '_');
public string GenerateRandomCodeVerifier()
{
byte[] bytes_verifier = new byte[32];
RandomNumberGenerator.Create().GetBytes(bytes_verifier);
string base64_verifier = Convert.ToBase64String(bytes_verifier);
string code_verifier = base64_verifier.ConvertInvalidWebCharacters();
return code_verifier;
}
public string GenerateCodeChallenge(string code_verifier)
{
using SHA256 sha256 = SHA256.Create();
byte[] byte_verifier = Encoding.UTF8.GetBytes(code_verifier);
byte[] byte_challenge = sha256.ComputeHash(byte_verifier);
string base64_challenge = Convert.ToBase64String(byte_challenge);
string code_challenge = base64_challenge.ConvertInvalidWebCharacters();
return code_challenge;
}
string code_verifier = GenerateRandomCodeVerifier();
string code_challenge = GenerateCodeChallenge(code_verifier);
Console.WriteLine($"code_verifier: {code_verifier}");
Console.WriteLine($"code_challenge: {code_challenge}");
Console.WriteLine("code_challenge_method: S256");