24
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[iOS] Facebookアカウントを使ってCognitoでAWSヘアクセス!!

Last updated at Posted at 2015-05-22

この記事で紹介すること

iOSアプリでFacebookアカウントを介してCognitoでAWSへアクセス!!
(AWS素人が調べた内容なので誤りがある可能性があります)

Facebook App の登録

Facebook認証をiOSアプリから利用するために、そのiOSアプリをFacebook Appとして登録する。

手順

1 https://developers.facebook.com/ にアクセス
2 My Apps からAdd a New Appを押して、AppIDを取得する.

スクリーンショット 2015-05-22 17.56.13.png

3 Getting Startedの内容に従って、iOSアプリからFacebookにログインできるようにする。(手順に従えば、Facebookログインボタンまで簡単に追加できるはず!!)

※ もし手順どおりInfo.plistにURL schemesも登録したのに、それが見つからない!!って怒られた場合は、Info.plistをテキスト形式で表示してみると良いかも。 FacebookAppIDの最初に空白が入ってたりするのに気づけるかもしれない...

スクリーンショット 2015-05-22 18.53.43.png

FacebookApp用のテストユーザーについて

FacebookAppのテスト用ユーザーを作成する場合は、My AppsページのRolesからTestUsersを作成できる。

スクリーンショット 2015-05-22 17.57.49.png

他のFacebookアカウントで認証するには

一度Facebookへ認証した後ログアウトするだけでは、他のユーザーで
認証できない(認証済みとして、勝手にログインしてしまう)。その場合はFacebookアプリの方で一度ログアウトすると、他のユーザーでログインできるようになる。

AWS Cognito

Identity pool の作成

1 AWS Cognitoのページにアクセス.(東京リージョンはまだない)
2 Create new Identity poolを選ぶ
3 Identity pool nameを入力する。(アプリ名など)
4 Unauthenticated identitiesを有効にするか選ぶ。(アプリが未認証のゲストユーザーを利用する場合は有効にする。今回は無効。)
5 Authentication providersを選択する。今回はFacebookを選び、FacebookAppのApp IDを入力する。

スクリーンショット 2015-05-22 18.00.02.png

6 認証用のIAMロールと未認証用のIAMロールの作成を許可する。

スクリーンショット 2015-05-22 18.04.10.png

IAM ロール ポリシーの編集.(必要であれば)

1 IAMページにアクセス.
2 ロールを選択.
スクリーンショット 2015-05-22 18.06.19.png

3 AWS Cognito Identity poolで作成した, __XXX__Auth_Roleを編集する。

4 例えばS3へユーザー毎にファイル追加と取得のアクセス許可を出す例.

前提
S3へ保存するファイルパスは、以下の形式.
mybucket/cognito-identity/ファイル名
※ cognito-identityがユーザーのID.


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}",
                "arn:aws:s3:::mybucket/${cognito-identity.amazonaws.com:sub}/*"
            ]
        }
    ]
}
  • ポリシー変数を利用するために、"Version": "2012-10-17"は必須。
  • ${cognito-identity.amazonaws.com:sub}は、cognitoで認証したユーザーのIDを表すポリシー変数。

参考

AWS STS ウェブ ID フェデレーションについて
http://docs.aws.amazon.com/ja_jp/STS/latest/UsingSTS/web-identity-federation.html

CognitoとFacebookログインの連携例

手順: Facebook認証できたら、CognitoへFacebookのtokenを設定して、AWSへ認証する.

AppDelegate


@implementation AppDelegate

// Cognitoのサンプルコードでは、Cognitoの認証をおこなっているけど、
// FacebookSDKの処理のみにする。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return [[FBSDKApplicationDelegate sharedInstance] application:application
                                    didFinishLaunchingWithOptions:launchOptions];
    
}

- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {
    return [[FBSDKApplicationDelegate sharedInstance] application:application
                                                          openURL:url
                                                sourceApplication:sourceApplication
                                                       annotation:annotation];
}

ViewController(Facebookのログインボタンを表示しているController)

便宜上ViewControllerでFacebookボタンを表示しているとする。


// ログイン/ログアウト結果を取得できるようにFBSDKLoginButtonDelegateを追加.
@interface ViewController : <FBSDKLoginButtonDelegate>

ログインボタン

参考
https://developers.facebook.com/docs/facebook-login/ios/v2.3
https://developers.facebook.com/docs/facebook-login/permissions

    FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
    loginButton.center = self.view.center;
    loginButton.readPermissions = @[@"public_profile", @"email"];
    // delete追加
    loginButton.delegate = self;
    [self.view addSubview:loginButton];

FBSDKLoginButtonDelegate実装

-(void)loginButton:(FBSDKLoginButton *)loginButton didCompleteWithResult:(FBSDKLoginManagerLoginResult *)result error:(NSError *)error {
  if( !error ) {
    if( !result.isCancelled ) {
        [self authorizeAWS];
    }
  }
}
-(void)authorizeAWS {
     NSDictionary* logins = @{@"graph.facebook.com": [FBSDKAccessToken currentAccessToken].tokenString};

    // AWS Cognitoのサンプルコード.
   
    AWSCognitoCredentialsProvider* credentialProvider =
        [[AWSCognitoCredentialsProvider alloc] initWithRegionType:CognitoRegionType /* Cognitoのリージョン */
    identityPoolId:CognitoIdentityPoolId /* CognitoのIdentityPoolId */];
    
    // ここでFacebookのログイン情報を設定.
    credentialProvider.logins = logins;
    
    AWSServiceConfiguration* configuration =
    [[AWSServiceConfiguration alloc] initWithRegion:DefaultServiceRegionType /* S3などサービスのあるリージョン */ credentialsProvider:credentialProvider];
    [AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
    
    self.credentialProvider = credentialProvider;


Cognitoで認証したユーザーIDの取得.

AWSCognitoCredentialsProvider::credentialProvider.getIdentityId で取得できるが、 以下のコードを実行しないとnilが返ってくる。

※ 適切な挿入箇所は未調査なので、とりあえず、上のauthorizedAWSメソッドの直後に実行してます。

stackoverflow
http://stackoverflow.com/questions/25245236/aws-cognito-identity-null

    // Cognitoのユーザー毎のIDを    
    [[credentialProvider getIdentityId] continueWithBlock:^id(BFTask *task){
        
        if (task.error == nil)
        {
            NSString* cognitoId = credentialProvider.identityId;
            NSLog(@"cognitoId: %@", cognitoId);
        }
        else
        {
            NSLog(@"Error : %@", task.error);
        }
        
        return nil;
    }];
}

ViewController初期化時


- (void)viewDidLoad {
    [super viewDidLoad];

	// 表示時にすでに認証済みなら、自動的にAWSヘログイン
    if( [FBSDKAccessToken currentAccessToken] ) {
        [self authorizeAWS];
    }
}

以上で、Facebookアカウントを介してAWSへアクセスができる。(間違いがある可能性は十分あります。気になる点があれば指摘ください.)

おまけ Facebookからログアウト

Facebookログインと同じ処理で、ログアウトボタンを表示できる。

    FBSDKLoginButton *loginButton = [[FBSDKLoginButton alloc] init];
    loginButton.center = self.view.center;
    loginButton.readPermissions = @[@"public_profile", @"email"];
    loginButton.delegate = self;
    [self.view addSubview:loginButton];

-(void)loginButtonDidLogOut:(FBSDKLoginButton *)loginButton {
    NSLog(@"logout facebook result.");
    [self.tableView reloadData];
    [loginButton removeFromSuperview];
    
    [self logoutAws];
}

-(void)logout {
    [self.credentialProvider clearCredentials];
    self.credentialProvider = nil;
}

おまけ Facebook profile(ユーザー名など)の取得.

Facebook認証に成功した後、遅れてprofileが取得できるようなので、NSNotificationCenterでProfile変化を受信できるようにする。



- (void)viewDidLoad {
    [super viewDidLoad];
    
    [FBSDKProfile enableUpdatesOnAccessTokenChange:YES];
    
    if(  [FBSDKAccessToken currentAccessToken] ) {
        [self authorizeAWS];
    }
        
    NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
    [center addObserver:self selector:@selector(fbSDKProfileDidChangeNotification:) name:FBSDKProfileDidChangeNotification object:nil];
}


-(void)fbSDKProfileDidChangeNotification:(NSNotificationCenter*)center {
    NSLog(@"something change...%@", [FBSDKProfile currentProfile]);
}

参考

Cognitoでユーザー認証:http://docs.aws.amazon.com/cognito/devguide/identity/?platform=ios

AWS STS ウェブ ID フェデレーションについて:
http://docs.aws.amazon.com/ja_jp/STS/latest/UsingSTS/web-identity-federation.html

24
25
1

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
24
25

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?