将使用Apple登录的功能添加到后端

在WWDC 2019上,Apple引入了新的用户授权系统-使用Apple登录。 有一项任务是将其集成到我们的后端,并使用电子邮件,Google和Facebook与现有的授权方法进行同步。 我们的同事kurenkoff承担了任务,他是本文的作者。 那些有兴趣的人请注意。

通过Apple进行的用户注册和授权程序



该过程非常原始,并且完全按照Apple的图示进行。

此外,Apple提供了更新令牌的功能:



该方案也很简单,可以验证令牌,但是我们不使用此功能,因为 我们不需要它。

通过AppleID实施授权


要通过AppleID实现授权,我们使用appleLogin包。 该软件包的作者犯了一些错误,但这些错误并不重要(某些错误是共同修复的)。 首先,您需要使用通过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 } 

然后获取令牌:

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

请务必注意哪个请求已发送到Apple服务器。 该文档说,要进行授权,必须发送client_id,client_secret,代码,grant_type和redirect_uri字段。 所有这些字段均按要求进行描述,但可以省略redirect_uri。 主要困难是client_secret-它是由WWDR门户上生成的密钥签名的JWT:

 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) 

Apple API将以错误响应或返回结构。 我们对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是包含用户数据的JWT令牌:

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

值得注意的是,只有在首次授权时才能接收电子邮件。 如果尝试重新授权,则只能获得一个ID(在“使用Apple登录”中的唯一用户标识符)。 要注册用户,我们需要足够的这些数据。

Source: https://habr.com/ru/post/zh-CN470175/


All Articles