LoginSignup
32
32

More than 5 years have passed since last update.

CognitoをSwiftで使ってFacebookログイン

Posted at

Amazon Cognitoは、モバイルアプリにおけるユーザ認証の仕組みを提供してくれるサービスです。
最近は家でSwiftを書いていて、認証機能を作ろうと思っていたところ、クラスメソッドさんのブログを発見しました。
Amazon Cognito でモバイルユーザー認証!

この記事はObjective-Cの例が取り上げられていたので、それをSwiftで書きなおしたという無いようです。

Amazon Cognitoとは

クラスメソッドさんのブログをご覧ください。

Facebookアプリ、Amazon Cognitoアイデンティティプールの設定

クラスメソッドさんのブログをご覧ください。

アプリの実装

podfileは本家と同様です。

まずはAppDelegate.swift。
ボタンをクリックしたらFacebook認証とCognitoの動作が始まります。

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let rootViewController = RootViewController()
        self.window!.rootViewController = rootViewController
        self.window!.backgroundColor = UIColor.whiteColor()
        self.window!.makeKeyAndVisible()
        return true
    }

    func application(application: UIApplication, openURL url: NSURL, sourceApplication: NSString?, annotation: AnyObject) -> Bool {
        FBSession.activeSession().handleOpenURL(url)
        var wasHandled:Bool = FBAppCall.handleOpenURL(url, sourceApplication: sourceApplication)
        return wasHandled
    }

    (中略)

    func applicationWillTerminate(application: UIApplication) {
        self.saveContext()
        FBSession.activeSession().close()
    }

次に本体の実装ですが、ViewとViewControllerで分けているので、本家とは別の構成になっていますが、ViewControllerには同様のものが書いてあります。

まずはViewから。

import UIKit

@objc protocol RootViewDelegae {
    func showTappedMessage() -> ()
}

class RootView : UIView {

    var delegate : RootViewDelegae!
    var loginButton : UIButton!

    func setTouchEvent() {
        self.loginButton!.addTarget(delegate, action: "showTappedMessage", forControlEvents: UIControlEvents.TouchUpInside)
    }

    func setInitialParams(view : UIView!) {
        self.loginButton = UIButton()
        self.loginButton?.setTitle("Login", forState: UIControlState.Normal)
        self.loginButton?.setTitleColor(UIColor.blueColor(), forState: UIControlState.Normal)
        self.loginButton?.setTitle("Tapped", forState: UIControlState.Highlighted)
        self.loginButton?.frame = CGRectMake(0, 0, 300, 50)
        self.loginButton?.tag = 1
        self.loginButton?.layer.position = CGPoint(x: 150, y: 500)
        self.loginButton?.backgroundColor = UIColor(red: 0.7, green: 0.2, blue: 0.2, alpha: 0.2)
        self.loginButton?.layer.cornerRadius = 10
        self.loginButton?.layer.borderWidth = 1
        view.addSubview(self.loginButton)
    }
}

そしてViewController


import UIKit

class RootViewController : UIViewController, RootViewDelegae {

    var rootView : RootView?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.rootView = RootView()
        self.view = self.rootView
        self.rootView!.delegate = self
        self.rootView!.setInitialParams(self.view)
        self.rootView!.setTouchEvent()
    }

    func showTappedMessage() {
        NSLog("hoge")
        var completionHandler : FBSessionStateHandler = {
            session, status, error in

            let cognitoAccountId = "0123456789"
            let cognitoIdentityPoolId = "us-east-1:123456-aaaa-bbbb-cccc-ddddeeeeffff"
            let cognitoUnauthRoleArn = "arn:aws:iam::0123456789:role/Cognito_sampleAuth_DefaultRole"
            let cognitoAuthRoleArn = "arn:aws:iam::0123456789:role/Cognito_sampleAuth_DefaultRole"

            if(status == FBSessionState.ClosedLoginFailed || status == FBSessionState.CreatedOpening) {
                NSLog("Login Failed")
                FBSession.activeSession().closeAndClearTokenInformation()
                FBSession.setActiveSession(nil)
            } else {
                NSLog("Login Succeed")
                FBSession.setActiveSession(session)

                let credentialsProvider : AWSCognitoCredentialsProvider = AWSCognitoCredentialsProvider.credentialsWithRegionType(
                    AWSRegionType.USEast1,
                    accountId: cognitoAccountId,
                    identityPoolId: cognitoIdentityPoolId,
                    unauthRoleArn: cognitoUnauthRoleArn,
                    authRoleArn: cognitoAuthRoleArn)

                var token : NSString = FBSession.activeSession().accessTokenData.accessToken

                var logins = NSDictionary(dictionary: ["graph.facebook.com" : token])
                credentialsProvider.logins = logins

                let defaultServiceConfiguration = AWSServiceConfiguration(
                    region: AWSRegionType.USEast1,
                    credentialsProvider: credentialsProvider)

                AWSServiceManager.defaultServiceManager().setDefaultServiceConfiguration(defaultServiceConfiguration)

                credentialsProvider.getIdentityId().continueWithSuccessBlock {
                    (task: BFTask!) -> AnyObject! in
                    let cognitoId : NSString = credentialsProvider.identityId
                    self.launchCount()
                    return nil
                }
            }
        }

        FBSession.openActiveSessionWithReadPermissions(["public_profile"], allowLoginUI: true, completionHandler: completionHandler)
    }

    func launchCount() {
        var syncClient : AWSCognito = AWSCognito.defaultCognito()
        var dataset : AWSCognitoDataset = syncClient.openOrCreateDataset("myDataset")

        dataset.synchronize()
        NSLog("Complete")
    }
}

アプリを起動しボタンをクリックした後にCognitoの管理画面に行くと、認証されていることがわかります。

※ スクリーンショット撮影前に2回認証をしたので、回数が1ではなくなっています。
スクリーンショット 2014-12-20 23.38.26.png

また、コンソールは以下の様なデバッグメッセージが出力されています。
スクリーンショット 2014-12-20 23.36.08.png

まとめ

ユーザ認証機能は、

  • アプリの提供価値そのものではない
  • しかしほぼ必須の機能である
  • そのくせ不具合が出やすく致命的

という厄介者です。

モバイルアプリ開発でもAmazonを使って、アプリケーションの本質に集中したいものです。

参考URL

32
32
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
32
32