现在Apple规定app必须支持删除账号的功能,而不能是简单的退出或者封禁账户。这是一个很好的举措,毕竟用户既然走到删除账户这一步,证明这个app并没有给用户带来理想的体验,所以也不希望预留个人信息在平台上。苹果额外规定如果使用AppleID登录,注销时也需要撤销AppleID的授权。
查看授权的路径
可以通过以下路径查看已授权AppleID登录的app:手机设置 》 Apple ID 》 密码与安全性 》 使用Apple ID的APP
撤销流程开始
一、获取撤销请求的token generate and validate tokens
1.1、接口地址
https://appleid.apple.com/auth/token
1.2、post
请求,请求的Content-Type
为application/x-www-form-urlencoded
1.3、请求参数
参数名 | 参数值 |
---|---|
client_id | app的bundle identifier |
client_secret | 字符串,生成方式看下面1.4章节介绍 |
code | 字符串,APP端用户调用apple id登录授权时,在public func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) 回调函数中的authorization.credential 是ASAuthorizationAppleIDCredential 类型,包含的authorizationCode 值, 可以使用String(data: authorizationCode, encoding: .utf8) 获得需要的值。这个值的有效期五分钟、并且是一次性的,所以如果用户注销的话,需要主动让用户再调用一次授权上传给服务器,以便请求撤销token |
grant_type | 字符串,写死 authorization_code |
其他参数是可选的,可以不用填写
1.4、client_secret生成
可以按照下面的操作步骤来生成client_secret,别漏掉咯
- 进入
Certificates, Identifiers & Profiles > Keys
,然后单击 Keys 旁边左上角的 + 号。 - 提供密钥名称并确保勾选
Sign In with Apple
。单击Configure
。在接下来出现的Configure Key
面板中,选择我们之前在Choose a Primary App ID
下使用的 App ID,然后单击保存。 - 单击
Continue
,然后在下一页中验证详细信息并单击Register
。 - 下载密钥并将其保存在安全的地方,因为您永远无法再次下载密钥。下载密钥后单击 Done。
- 电脑安装Ruby的环境,mac默认已经安装,终端运行命令
sudo gem install jwt
来安装ruby-jwt
。 - 新创建一个文本文件,secret_gen.rb文件,内容如下,修改一下里面的参数,对应的含义已经注释过
require "jwt"
key_file = "Path to the private key" #刚刚下载的p8文件的本地路径
team_id = "Your Team ID" #开发账号的team ID,在https://developer.apple.com/account/的Membership中查看
client_id = "The Service ID of the service you created" #app的`bundle identifier`
key_id = "The Key ID of the private key" #生成那个p8文件时的key id,在Certificates, Identifiers & Profiles > Keys点击生成的key中查看,默认就是那个p8文件名中的编号
validity_period = 180 # In days. Max 180 (6 months) according to Apple docs.
private_key = OpenSSL::PKey::EC.new IO.read key_file
token = JWT.encode(
{
iss: team_id,
iat: Time.now.to_i,
exp: Time.now.to_i + 86400 * validity_period,
aud: "https://appleid.apple.com",
sub: client_id
},
private_key,
"ES256",
header_fields=
{
kid: key_id
}
)
puts token
编辑保存之后,在终端运行这个文件ruby secret_gen.rb
即可获得对应的client_secret
二、撤销token
上面第一步请求之后,会获取到对应用户的token
,然后拿上一步的token
去撤销AppleID授权
2.1、接口地址
https://appleid.apple.com/auth/token
2.2、post
请求,请求的Content-Type
为application/x-www-form-urlencoded
2.3、请求参数
参数名 | 参数值 |
---|---|
client_id | app的bundle identifier |
client_secret | 第一步1.4章节生成的client_secret |
token | 字符串,第一步请求拿到的token |
token_type_hint | 字符串,写死 access_token |
请求之后即可成功
三、验证
验证步骤很简单,撤销成功之后,在手机设置中查看使用Apple ID的APP,里面不再包含你的app,同时在你的app中重新请求AppleID登录时,也会重新弹出授权弹窗。这就证明之前的那个AppleID已经成功撤销了。
四、vapor的实现
vapor是一个swift开发的服务器框架,如果你服务器是用的这个,可以查看这个实现的demo,参数修改成你自己的app。其他框架根据上面实现的三步即可
4.1、token返回值
import Vapor
final class Cont_AppleToken: Content {
var access_token: String?
var token_type: String?
var expires_in: Int?
var refresh_token: String?
var id_token: String?
}
4.2、请求撤销类
import Vapor
class AppleRevokeTool {
//获取撤销请求的token
func generateToken(_ req: Request, appleAuthorizationCode: String) throws -> EventLoopFuture<Cont_AppleToken> {
return req.client.post("https://appleid.apple.com/auth/token") { tokenReq in
// Encode JSON to the request body.
try? tokenReq.content.encode(["client_id": "com.lazypig.cicada", "client_secret": AppleLoginClientSecret, "code": appleAuthorizationCode, "grant_type": "authorization_code"])
tokenReq.headers.add(name: "Content-Type", value: "application/x-www-form-urlencoded")
}.flatMapThrowing { res in
try res.content.decode(Cont_AppleToken.self)
}
}
//撤销token
func revokeToken(_ req: Request, token: String) -> EventLoopFuture<HTTPStatus> {
return req.client.post("https://appleid.apple.com/auth/revoke") { tokenReq in
// Encode JSON to the request body.
try? tokenReq.content.encode(["client_id": "com.lazypig.cicada", "client_secret": AppleLoginClientSecret, "token": token, "token_type_hint": "access_token"])
tokenReq.headers.add(name: "Content-Type", value: "application/x-www-form-urlencoded")
}.map { clientResponse in
return clientResponse.status
}
}
}
4.3、请求撤销
//撤销apple ID的授权,appleAuthorizationCode为app上传上来的用户code
let revokeTool = AppleRevokeTool()
_ = try? revokeTool.generateToken(req, appleAuthorizationCode: appleAuthorizationCode).flatMap { cont_AppleToken -> EventLoopFuture<HTTPStatus> in
if let token = cont_AppleToken.access_token {
return revokeTool.revokeToken(req, token: token).map({ status -> HTTPStatus in
return status
})
}
return req.eventLoop.future(HTTPStatus.ok)
}
参考链接
- Apple 注销账户 Revoke Token
- iOS 探究 | 第九篇 Sign in with apple 及撤销令牌(Revoke Tokens)详细探究
- sign_in_with_apple/revoke_tokens
- generate_and_validate_tokens
版权属于:东哥笔记 - DongGe.org
本文链接:https://dongge.org/blog/1190.html
自2017年12月26日起,『转载以及大段采集进行后续编辑』须注明本文标题和链接!否则禁止所有转载和采集行为!