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ではなくなっています。
また、コンソールは以下の様なデバッグメッセージが出力されています。
まとめ
ユーザ認証機能は、
- アプリの提供価値そのものではない
- しかしほぼ必須の機能である
- そのくせ不具合が出やすく致命的
という厄介者です。
モバイルアプリ開発でもAmazonを使って、アプリケーションの本質に集中したいものです。