LoginSignup
6
2

More than 5 years have passed since last update.

Google Sign-In for iOS ケーススタディ

Last updated at Posted at 2017-01-17

はじめに

iOSにおいて、GoogleのOAuth認証は Google Sign-In for iOS というSDKを用いれば簡単に実現できます。
ただ、認証情報としてMobileSafariのキャッシュを用いている関係で状態管理が複雑なうえに、公式のドキュメントに書かれている情報は手順くらいで、「こういう時にこういう値が返る」などの情報がありません。

そこで本記事では、「こういう仕様にしたいんだけど、どうすれば良いんだろう」「外部ブラウザに引っ張られないで、一貫したUXにしたい」などという場合に考えられるケースと、その解決策を書いていきます。

主にセキュリティ面で、Googleが推奨している実装にはなっていない可能性があります。
また、サンプルコードはSwiftではなくObjective-Cで書いています。
ご了承ください。

ケース1: AppDelegate.m 以外の箇所にGIDSignInDelegateのメソッドが書きたい

諦めましょう。まずコンパイラに怒られます。
詳しくはこちらをご参照ください。

で、例えばViewControllerでサインイン後の処理がしたい場合は、下記のようにGIDSignInDelegateのメソッドからNotificationを飛ばすのが良いでしょう。
(@"MyNotification" などは定数化してあげましょう)

AppDelegate.m
- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error
{
    // 取得したユーザーのプロフィールや認証情報など、通知を受け取る側に渡す値を生成する
    NSDictionary * info = @{
                           @"email": user.profile.email,
                           @"error": error
                           };

    // Notificationを飛ばす
    NSNotification * n = [NSNotification notificationWithName:@"MyNotification" object:self userInfo:info];
    [[NSNotificationCenter defaultCenter] postNotification:n];
}
MyViewController.m
- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    // Notificationを登録する
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(foo:) name:@"MyNotification" object:nil];
}

- (void)viewWillDisappear:(BOOL)animated
{
    // Notificationの登録を解除する
    [[NSNotificationCenter defaultCenter removeObserver:self name:@"MyNotification" object:nil];

    [super viewWillDisappear:animated];
}

- (void)foo:(NSNotification *)n
{
    // サインインが実行された後、Notificationを受け取る処理
    // n.userInfo で通知と一緒に渡された値を取り出すことができる
    [n.userInfo objectForKey:@"email"];
}

ケース2: 余計な権限を要求してくる

Google Sign-Inは、デフォルトで「メールアドレスの表示」「ユーザーのプロフィール情報の表示」の2つの権限を要求してきます。
default_scope.png
スコープの情報はこちらの公式ドキュメントのprofileとemailです。

GIDSignInインスタンスのプロパティshouldFetchBasicProfileをNOに設定すると、これらの権限の要求がなくなります。

YouTube Data APIを使用するためYouTubeのチャンネルの情報しか使用しないなど、これらのスコープが必要ないケースが出てくると思います。
以下にGoogleアカウントに紐づいているYouTubeの情報しか権限を要求させないための実装を示します。

GIDSignIn * signIn = [GIDSignIn sharedInstance];
signIn.scopes = @[
                  @"https://www.googleapis.com/auth/youtube.upload",
                  @"https://www.googleapis.com/auth/youtube.readonly"
                  ];
signIn.shouldFetchBasicProfile = NO;
[signIn signIn];

おわりに

・・・もっといろいろあった気がしますが、今思い出せるのはこれくらいです。
何かありましたら随時更新していきます。まだまだ検証したいところもありますね。

6
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
2