Sign in with Apple ——iOS苹果登录

如果你的app只能通过微信、google、facebook等三方账号登录,则你的app也需要集成AppId登录,也就是Sign in with Apple。

1. 什么是 Sign in with Apple

Sign in with Apple是苹果在WWDC2019推出的,作用同微信登录一样,用户可以通过手机上的AppId账号登录别的应用。
Sign in with Apple支持iOS13以上的iOS手机,同时也支持网页端使用appId登录。

官方文档推荐:

WWDC2019 Sign In With Apple 视频
Sign in with Apple快速开始
Apple登录更新指南

2. 在苹果后台配置Sigin in with Apple相关证书

image.png
  1. 登录Apple开发者账号,点击Certificates,Identifiers & Profiles
    image.png
  2. 【添加appId】
  • 选中左边的Identifiers之后,再点击右边Identifiers旁边的+号按钮
  • 之后选中App IDs,再点击右上角的Continue
  • 在下一页选择App,再点击右上角的Continue
  • 来到Register an App ID页面,这里的Description随便输入,例如:mobile, BundleID这里就输入应用的包名,例如:com.wing.mobile。在Capabilities* 这里向下滑动页面到Sign In with Apple,然后将其勾选。再点击右上角的Continue
  • 来到Confirm your App ID页面之后,直接点击右上角的Register
  1. 【添加Keys】
  • 选中左边的Keys之后,再点击右边Keys旁边的+号按钮
  • 来到Register a New Key页面,在key Name输入框输入:mobile sign in,勾选中Sign in with Apple并点击旁边的Configure
  • 来到Configure Key页面,点击下拉框选中com.wing.mobile,再点击右上角的Save
  • 回到Register a New Key页面后直接点击右上角的Continue,之后再点击Register完成Keys的添加
  • 点击Download下载你的key【注意:下载之后一定要备份,因为下载之后苹果后台就会把这个key删除掉】
  • 记录下自己的Key ID,大概是V2ZJ2K4SMC这个样子

3. iOS客户端集成Sign in with Apple

前置条件

  • iOS 13以上真机
  • Xcode 11以上
  • 电脑macos 10.15以上

工程配置

添加Sign in with Apple.png

AppId登录代码

导入头文件:#import

  1. 添加登录按钮
- (void)setupUI {
    ASAuthorizationAppleIDButton *btn = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeSignIn style:ASAuthorizationAppleIDButtonStyleBlack];
    btn.frame = CGRectMake(50, 150, 200, 50);
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}
  1. 当点击登录按钮时请求appId登录
- (void)btnClick:(UIButton *)btn {
    if (@available(iOS 13.0, *)) {
        ASAuthorizationAppleIDProvider *provider = [ASAuthorizationAppleIDProvider new];
        ASAuthorizationAppleIDRequest *request = provider.createRequest;
        request.requestedScopes = @[ASAuthorizationScopeEmail, ASAuthorizationScopeFullName];
        ASAuthorizationController *vc = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        vc.delegate = self;
        vc.presentationContextProvider = self;
        [vc performRequests];
    }
}
  1. 实现AppId登录回调代理
#pragma mark - ASAuthorizationControllerDelegate
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization {
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *credential = authorization.credential;
        NSString *user = credential.user;
        NSData *identifyToken = credential.identityToken;
        NSData *authCode = credential.authorizationCode;
        NSString *codeStr = [[NSString alloc] initWithData:authCode encoding:NSUTF8StringEncoding];
        NSLog(@"user = %@, authCode = %@", user, codeStr);
    } else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
        ASPasswordCredential *credential = authorization.credential;
        NSLog(@"password = %@", credential.password);
    } else {
        NSLog(@"授权信息不符");
    }
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error {
    NSLog(@"[Wing] error = %@", error);
}

完整的ViewController.m代码如下,可直接拷贝到Demo项目中使用

#import "ViewController.h"
#import 

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setupUI];
}

/// 添加点击按钮
- (void)setupUI {
    ASAuthorizationAppleIDButton *btn = [ASAuthorizationAppleIDButton buttonWithType:ASAuthorizationAppleIDButtonTypeSignIn style:ASAuthorizationAppleIDButtonStyleBlack];
    btn.frame = CGRectMake(50, 150, 200, 50);
    [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];

}

/// 请求appId登录
- (void)btnClick:(UIButton *)btn {
    if (@available(iOS 13.0, *)) {
        ASAuthorizationAppleIDProvider *provider = [ASAuthorizationAppleIDProvider new];
        ASAuthorizationAppleIDRequest *request = provider.createRequest;
        request.requestedScopes = @[ASAuthorizationScopeEmail, ASAuthorizationScopeFullName];
        
        ASAuthorizationController *vc = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[request]];
        vc.delegate = self;
        vc.presentationContextProvider = self;
        [vc performRequests];
    }
    
}

/// AppId登录回调
#pragma mark - ASAuthorizationControllerDelegate
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization {
    if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
        ASAuthorizationAppleIDCredential *credential = authorization.credential;
        NSString *user = credential.user;
        NSData *identifyToken = credential.identityToken;
        NSData *authCode = credential.authorizationCode;
        NSString *codeStr = [[NSString alloc] initWithData:authCode encoding:NSUTF8StringEncoding];
        NSLog(@"user = %@, authCode = %@", user, codeStr);
    } else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]) {
        ASPasswordCredential *credential = authorization.credential;
        NSLog(@"password = %@", credential.password);
    } else {
        NSLog(@"授权信息不符");
    }
}

- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error {
    NSLog(@"[Wing] error = %@", error);
}

4. Sign in with Apple服务端验证

服务端验证一共需要3个参数:

  1. client_id:也就是客户端的包名,本例中是:com.wing.mobile【注意:Web端的client_id和客户端是不一样的】
  2. client_secret:需要通过加密算法生成,最长有效期180天
  3. code:每次appId登录成功后客户端获取到的authorizationCode的data转成的字符串

client_secret生成

  1. 终端执行sudo gem install jwt安装jwt
  2. 添加下面需要的信息并将内容保存为secret_gen.rb
require "jwt"
key_file = "Path to the private key" # 一个.p8文件,在添加Key时最后一步那个只能下载一次的文件
team_id = "Your Team ID" # 10个字节的字符串,可以在苹果账户后台中看到,位于右上角
client_id = "Bundle ID" # 客户端是bundleId,网页端是servicesId
key_id = "The Key ID of the private key" # V2ZJ2K4SMC
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
  1. 终端执行命令ruby secret_gen.rb运行secret_gen.rb,之后终端会输入client_secret

curl 验证

curl -v POST "https://appleid.apple.com/auth/token" \
-H 'content-type: application/x-www-form-urlencoded' \
-d 'client_id=com.match.woohoo' \
-d 'client_secret=eyJraWQiOiJNMzQ5RDZVNDY2IiwiYWxnIjoiRVMyNTYifQ.eyJpc3MiOiJGU0hYV1c2NjhTIiwiaWF0IjoxNjE2MTMyOTE5LCJleHAiOjE2MzE2ODQ5MTksImF1ZCI6Imh0dHBzOi8vYXBwbGVpZC5hcHBsZS5jb20iLCJzdWIiOiJjb20ubWF0Y2gud29vaG9vIn0.zFWtXv1CCZ3KTgSWoiARYlowZjbUon_cMuHZQZg36eAcsxgIxGBCWWZXqRVZxa2fil0ipguRIZF28AjXi3APGw' \
-d 'code=c9755915369ad47169813487f0e6c1ea2.0.rrwrv.ZWwChKXLiTlh1lsXHvlC3A' \
-d 'grant_type=authorization_code'

参考文章

  1. iOS开发:Sign In With Apple(使用Apple登录)
  2. 快速配置 Sign In with Apple

你可能感兴趣的:(Sign in with Apple ——iOS苹果登录)