Adicione o login com a Apple ao back-end

Na WWDC 2019, a Apple introduziu um novo sistema de autorização de usuário - Entre com a Apple. Havia uma tarefa de integrá-lo ao nosso back-end e sincronizá-lo com os métodos de autorização existentes usando email, Google e Facebook. Nosso colega Kurenkoff assumiu a tarefa, ele é o autor deste artigo. Os interessados ​​são solicitados sob cat.

Procedimento de registro e autorização de usuário através da Apple



O procedimento é bastante primitivo e ocorre exatamente como indicado no diagrama da Apple.

Além disso, a Apple oferece a capacidade de atualizar o token:



O esquema também é bastante simples, é possível verificar o token, mas não usamos esse recurso, porque nós não precisamos disso.

Implementar autorização através do AppleID


Para implementar a autorização via AppleID, usamos o pacote appleLogin . O autor deste pacote cometeu alguns erros, mas eles não são críticos (e alguns foram corrigidos em conjunto). Primeiro de tudo, você precisa inicializar a configuração usando os dados recebidos pelo portal de desenvolvedores da Apple.

config := appleLogin.InitAppleConfig( TeamID, // ID   developer.apple.com,   iOS  ClientID, // Bundle  iOS  callbackURI, //       KeyID, //     developer.apple.com,   iOS  ) privateKey := os.Getenv("PRIVATE_KEY") err := config.LoadP8CertByByte([]byte(privateKey)) if err != nil { return nil, err } 

Em seguida, obtenha o token:

 token, err := config.GetAppleToken(clientToken, tokenExpireTime) if err != nil { return nil, err } 

É importante observar qual solicitação é enviada ao servidor Apple. A documentação diz que, para autorização, é necessário enviar os campos client_id, client_secret, code, grant_type, redirect_uri. Todos esses campos são descritos conforme necessário, mas o redirect_uri pode ser omitido. A principal dificuldade é client_secret - é um JWT assinado por uma chave gerada no portal WWDR:

 token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{ "iss": a.TeamID, "iat": time.Now().Unix(), "exp": time.Now().Unix() + expireTime, "aud": "https://appleid.apple.com", "sub": a.ClientID, }) token.Header = map[string]interface{}{ "kid": a.KeyID, "alg": "ES256", } tokenString, _ := token.SignedString(a.AESCert) 

A API da Apple responderá com um erro ou retornará uma estrutura. Estamos interessados ​​no campo IDToken:

 type AppleAuthToken struct { AccessToken string json:"access_token" //AccessToken ExpiresIn int64 json:"expires_in" //Expires in IDToken string json:"id_token" //ID token RefreshToken string json:"refresh_token" //RF token TokenType string json:"token_type" //Token Type } 

IDToken é um token JWT que contém dados do usuário:

 type AppleUser struct { ID string json:"sub,omitempty" Email string json:"email,omitempty" EmailVerified bool json:"email_verified,string,omitempty" } 

Vale a pena prestar atenção ao fato de que o email pode ser recebido somente na primeira autorização. Se você tentar autorizar novamente, poderá obter apenas um ID (um identificador de usuário exclusivo em Entrar com a Apple). Para registrar um usuário, precisamos desses dados em quantidade suficiente.

Source: https://habr.com/ru/post/pt470175/


All Articles