Skip to content

Instantly share code, notes, and snippets.

@dmennis
Last active December 13, 2018 22:43
Show Gist options
  • Save dmennis/847434d75f63ec1dee9e574ca2aad3e7 to your computer and use it in GitHub Desktop.
Save dmennis/847434d75f63ec1dee9e574ca2aad3e7 to your computer and use it in GitHub Desktop.
AWSMobileClient code for implementing basic auth or federated login using the AWS SDK for iOS and AWS Amplify Framework (CLI) - 2.7.0+
//
// AuthViewController.swift
//
// Created by Hills, Dennis on 12/13/2018.
// Copyright © 2018 Hills, Dennis. All rights reserved.
//
// About: Using AWS Amplify Framework for iOS 2.7.0+ to implement Basic Auth via Cognito User Pools with example Facebook option
// This sample includes the userState listener and AWSMobileClient implementation changes added to iOS SDK for AWS v.2.7.0+
//
// AWS Amplify Documentation: https://aws-amplify.github.io/docs/ios/authentication
// Basic Auth via User Pools blog: https://itnext.io/basic-authentication-for-ios-using-aws-amplify-and-amazon-cognito-233b943222d4
// Facebook Login via Cognito Identity Pools (with User Pools, too): https://itnext.io/facebook-login-using-aws-amplify-and-amazon-cognito-4acf74875a04
// Google Sign-In: https://itnext.io/google-sign-in-using-aws-amplify-and-amazon-cognito-69cc3bf219ad
// Login with Amazon blog via Cognito Identity Pools only: https://itnext.io/federated-identities-using-login-with-amazon-with-amazon-cognito-and-aws-amplify-bfb7dfb7e185
//
// # High level steps to implement Facebook auth into your iOS apps with AWS
// [Prerequisites]
// Create a basic single view controller iOS (Swift) Xcode project
// Install & configure AWS Amplify Framework (CLI - https://aws-amplify.github.io): $ npm install -g @aws-amplify/cli
// [Backend]
// Amplify init (from Xcode project folder)
// Amplify add auth (or Amplify update auth)
// Amplify push
// [Client]
// Add AWSConfiguration.swift to your xcode project
// Pod init
// Add AWSMobileClient dependancies to Podfile
// Pod install --repo-update
// Add this code to your ViewController (No singleton required in the AppDelegate)
// *NOTE* Make sure the ViewController has a NavigationController if you are using the Auth UI as part of the AWS SDK for iOS
import UIKit
import AWSMobileClient
import FBSDKLoginKit // FACEBOOK ONLY: Used for signing out of Facebook. FB SDK installed by AWS SDK for iOS
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
initializeAWSMobileClient() // Initialize the AWSMobileClient
}
// Initializing the AWSMobileClient and take action based on current user state
func initializeAWSMobileClient() {
AWSMobileClient.sharedInstance().initialize { (userState, error) in
self.addUserStateListener() // Register for user state changes
if let userState = userState {
switch(userState){
case .signedIn: // is Signed IN
print("Logged In")
print("Cognito Identity Id (authenticated): \(String(describing: AWSMobileClient.sharedInstance().identityId))")
case .signedOut: // is Signed OUT
print("Logged Out")
print("Cognito Identity Id (unauthenticated): \(String(describing: AWSMobileClient.sharedInstance().identityId))")
DispatchQueue.main.async {
self.showSignIn()
}
case .signedOutUserPoolsTokenInvalid: // User Pools refresh token INVALID
print("User Pools refresh token is invalid or expired.")
DispatchQueue.main.async {
self.showSignIn()
}
case .signedOutFederatedTokensInvalid: // Login with Amazon, Facebook, Google, or Twitter refresh token INVALID
print("Federated refresh token is invalid or expired.")
DispatchQueue.main.async {
self.showSignIn()
}
default:
AWSMobileClient.sharedInstance().signOut()
}
} else if let error = error {
print(error.localizedDescription)
}
}
}
// Use the iOS SDK drop-in Auth UI to show login options to user (Basic auth, Google, or Facebook)
// Note: The view controller implementing the drpo-in auth UI needs to be associated with a Navigation Controller.
func showSignIn() {
AWSMobileClient.sharedInstance().showSignIn(navigationController: self.navigationController!, {
(userState, error) in
if(error == nil){ // Successful signin
DispatchQueue.main.async {
print("User successfully logged in")
}
}
})
}
// AWSMobileClient - realtime notifications on user state changes
// This is super useful for immediately taking action when a refresh token has expired or a user has logged out
func addUserStateListener() {
AWSMobileClient.sharedInstance().addUserStateListener(self) { (userState, info) in
switch (userState) {
case .guest:
print("Listener: guest")
print("Cognito Identity Id (unauthenticated): \(String(describing: AWSMobileClient.sharedInstance().identityId))")
case .signedIn:
print("Listener: signedIn") // Called after successful login with User Pools or Federated login via drop-in auth UI
print("Cognito Identity Id (authenticated): \(String(describing: AWSMobileClient.sharedInstance().identityId))")
case .signedOut:
print("Listener: signedOut") // Triggered by AWSMobileClient.sharedInstance().signOut()
print("Cognito Identity Id (authenticated): \(String(describing: AWSMobileClient.sharedInstance().identityId))")
case .signedOutUserPoolsTokenInvalid: // Cognito User Pools refresh token is invalid
print("Listener: signedOutUserPoolsTokenInvalid")
case .signedOutFederatedTokensInvalid: // Facebook, Google, Login with Amazon, or Twitter refresh token invalid
print("Listener: signedOutFederatedTokensInvalid")
default:
print("unsupported userstate")
}
}
}
func signOut() {
AWSMobileClient.sharedInstance().signOut()
// FACEBOOK ONLY - Use to sign out the user from Facebook (good for testing or allowing the user to login as another FB user)
let manager = FBSDKLoginManager()
manager.logOut()
}
override func viewDidDisappear(_ animated: Bool) {
// Remove the AWSMobileClient user state listener when this VC goes away
// AWSMobileClient.sharedInstance().removeUserStateListener(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment