At WWDC 2019, Apple introduced a new user authorization system - Sign in with Apple. There was a task to integrate it into our back-end and synchronize it with existing authorization methods using email, Google and Facebook. Our colleague
kurenkoff took up the task, he is the author of this article. Those interested are requested under cat.
User registration and authorization procedure through Apple
The procedure is quite primitive and occurs exactly as indicated on the diagram from Apple.
In addition, Apple provides the ability to update the token:
The scheme is also quite simple, it is possible to do token verification, but we do not use this feature, because we do not need it.
Implement authorization through AppleID
To implement authorization through AppleID, we use the
appleLogin package. The author of this package made some mistakes, but they are not critical (and some were jointly fixed). First of all, you need to initialize the config using the data received through the Apple developer portal.
config := appleLogin.InitAppleConfig( TeamID,
Then get the token:
token, err := config.GetAppleToken(clientToken, tokenExpireTime) if err != nil { return nil, err }
It is important to note which request is sent to the Apple server. The
documentation says that for authorization it is necessary to send the client_id, client_secret, code, grant_type, redirect_uri fields. All of these fields are described as required, but redirect_uri can be omitted. The main difficulty is client_secret - this is a JWT signed by a key generated on the WWDR portal:
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)
The Apple API will either respond with an error or return a structure. We are interested in the IDToken field:
type AppleAuthToken struct { AccessToken string json:"access_token"
IDToken is a JWT token containing user data:
type AppleUser struct { ID string json:"sub,omitempty" Email string json:"email,omitempty" EmailVerified bool json:"email_verified,string,omitempty" }
It is worth paying attention to the fact that email can be received only at the first authorization. If you try to reauthorize, you can only get an ID (a unique user identifier in Sign in with Apple). To register a user, we need enough of these data.