Conceitos básicos da AWS

Criar uma aplicação iOS

Criar uma aplicação iOS simples usando o AWS Amplify

Módulo 3: adicionar autenticação

Neste módulo, você usará as bibliotecas e a CLI do Amplify para configurar e adicionar autenticação a seu aplicativo.

Introdução

O próximo recurso a ser adicionado é a autenticação de usuário. Neste módulo, você aprenderá como autenticar um usuário com as bibliotecas e a CLI do Amplify utilizando o Amazon Cognito, um serviço gerenciado de identidade de usuários.

Você aprenderá também como usar a interface de usuário hospedada pelo Cognito para apresentar um fluxo de autenticação de usuário completo, permitindo que os usuários se cadastrem, façam login e redefinam suas senhas, com apenas algumas linhas de código.

Usar uma "interface de usuário hospedada" significa que a aplicação aproveita as páginas da Web do Cognito para os fluxos de interface de usuário de login e cadastro. O usuário do aplicativo é redirecionado para uma página da Web hospedada pelo Cognito e redirecionado ao aplicativo após o login. Certamente, o Cognito e o Amplify também oferecem suporte à IU nativa, e você pode seguir as instruções deste workshop para saber mais sobre a IU de autenticação personalizada.

O que você aprenderá

  • Criar e implantar um serviço de autenticação
  • Configurar seu aplicativo iOS para incluir a autenticação de IU hospedada pelo Cognito

Conceitos principais

Bibliotecas do Amplify – As bibliotecas do Amplify permitem interagir com os serviços da AWS de uma aplicação móvel ou Web.

Autenticação – Em software, autenticação é o processo de verificação e gerenciamento da identidade de um usuário, usando um serviço de autenticação ou API.

 Tempo para a conclusão

10 minutos

 Serviços usados

Implementação

  • Criar o serviço de autenticação

    Para criar o serviço de autenticação, abra um terminal e execute este comando:

    amplify add auth
    
    ? Do you want to use the default authentication and security configuration? Select Default configuration with Social Provider and press enter
    ? How do you want users to be able to sign in? Select the default Username and press enter
    ? Do you want to configure advanced settings? Select the default No, I am done and press enter
    ? What domain name prefix do you want to use? Select the default and press enter
    Enter your redirect signin URI: type gettingstarted:// and press enter
    ? Do you want to add another redirect signin URI? Select the default N and press enter
    Enter your redirect signout URI: type gettingstarted:// and press enter
    ? Do you want to add another redirect signout URI? Select the default N and press enter
    ? Select the social providers you want to configure for your user pool: do not select any provider and press enter

    Você saberá que a configuração teve êxito quando vir esta mensagem (o nome exato do recurso pode variar):

    Successfully added resource iosgettingstartedfc5a4717 locally
  • Implantar o serviço de autenticação

    Agora que o serviço de autenticação foi configurado localmente, podemos implantá-lo na nuvem. Em um terminal, execute este comando no diretório do seu projeto:

    amplify push
    
    # press Y when asked to continue

    Depois de um tempo, você verá a seguinte mensagem:

    ✔ All resources are updated in the cloud
    
    Hosted UI Endpoint: https://iosgettingstarted-dev.auth.eu-central-1.amazoncognito.com/
    Test Your Hosted UI Endpoint: https://iosgettingstarted-dev.auth.eu-central-1.amazoncognito.com/login?response_type=code&client_id=1234567890&redirect_uri=gettingstarted://
  • Adicionar biblioteca de autenticação do Amplify ao projeto

    Antes de acessar o código, você adiciona a biblioteca de autenticação do Amplify às dependências do projeto. Abra o arquivo Podfile e adicione a linha com AmplifyPlugins/AWSCognitoAuthPlugin ou copie/cole o arquivo inteiro a seguir.

    # you need at least version 13.0 for this tutorial, more recent versions are valid too
    platform :ios, '13.0'
    
    target 'getting started' do
      # Comment the next line if you don't want to use dynamic frameworks
      use_frameworks!
    
      # Pods for getting started
      pod 'Amplify', '~> 1.0'                             # required amplify dependency
      pod 'Amplify/Tools', '~> 1.0'                       # allows to call amplify CLI from within Xcode
    
      pod 'AmplifyPlugins/AWSCognitoAuthPlugin', '~> 1.0' # support for Cognito user authentication
    
    end

    Em um terminal, execute o comando:

    pod install

    O comando leva alguns segundos para ser concluído. Você deve ver isto (os números da versão real podem variar):

    Analyzing dependencies
    Downloading dependencies
    Installing AWSAuthCore (2.14.1)
    Installing AWSCognitoIdentityProvider (2.14.1)
    Installing AWSCognitoIdentityProviderASF (1.0.1)
    Installing AWSCore (2.14.1)
    Installing AWSMobileClient (2.14.1)
    Installing AWSPluginsCore (1.0.4)
    Installing AmplifyPlugins (1.0.4)
    Generating Pods project
    Integrating client project
    Pod installation complete! There are 3 dependencies from the Podfile and 8 total pods installed.
  • Configurar a biblioteca de autenticação do Amplify em tempo de execução

    De volta ao Xcode, abra o arquivo Backend.swift. Na classe Backend,

    • adicione uma instrução de importação a AmplifyPlugins
    • adicione uma linha ao código de inicialização do Amplify que adicionamos na seção anterior.

    Veja a seguir a aparência do bloco de códigos completo:

    // at the top of the file
    import AmplifyPlugins
    
    private init () {
      // initialize amplify
      do {
         try Amplify.add(plugin: AWSCognitoAuthPlugin())
         try Amplify.configure()
         print("Initialized Amplify")
      } catch {
         print("Could not initialize Amplify: \(error)")
      }
    }

    Para verificar se tudo funciona conforme o esperado, compile o projeto. Clique no menu Product (Produto) e selecione Build (Compilar) ou digite ⌘B. Não deve aparecer nenhum erro.

  • Acionar autenticação em tempo de execução

    A alteração restante do código acompanha o status de um usuário (se ele fez login ou não) e aciona a interface de usuário de login/cadastro quando o usuário não fez login. 

    a. Adicione o código SignIn e SignOut. Em qualquer lugar da classe Backend, adicione os três seguintes métodos:

     

    // MARK: - User Authentication
    
    // signin with Cognito web user interface
    public func signIn() {
    
        _ = Amplify.Auth.signInWithWebUI(presentationAnchor: UIApplication.shared.windows.first!) { result in
            switch result {
            case .success(_):
                print("Sign in succeeded")
            case .failure(let error):
                print("Sign in failed \(error)")
            }
        }
    }
    
    // signout
    public func signOut() {
    
        _ = Amplify.Auth.signOut() { (result) in
            switch result {
            case .success:
                print("Successfully signed out")
            case .failure(let error):
                print("Sign out failed with error \(error)")
            }
        }
    }
    
    // change our internal state, this triggers an UI update on the main thread
    func updateUserData(withSignInStatus status : Bool) {
        DispatchQueue.main.async() {
            let userData : UserData = .shared
            userData.isSignedIn = status
        }
    }

    b. Adicionar um listener de hub de autenticação

    Para acompanhar as alterações no status de autenticação, adicionamos um código para assinar os eventos de autenticação enviados pelo Amplify. Inicializamos o hub no método Backend.init().

    Quando um evento de autenticação é recebido, chamamos o método updateUserData(). Esse método mantém o objeto UserData sincronizado. A propriedade UserData.isSignedIn é @Published, ou seja, a interface de usuário é atualizada automaticamente quando há alterações no valor. 

    Também adicionamos um código para verificar o status de autenticação anterior no momento da inicialização da aplicação. Quando a aplicação é iniciada, ela verifica se já existe uma sessão do Cognito e atualiza a IU conforme adequado.

    No Backend.init(), adicione o seguinte código após a inicialização do Amplify:

    // in private init() function
    // listen to auth events.
    // see https://github.com/aws-amplify/amplify-ios/blob/master/Amplify/Categories/Auth/Models/AuthEventName.swift
    _ = Amplify.Hub.listen(to: .auth) { (payload) in
    
        switch payload.eventName {
    
        case HubPayload.EventName.Auth.signedIn:
            print("==HUB== User signed In, update UI")
            self.updateUserData(withSignInStatus: true)
    
        case HubPayload.EventName.Auth.signedOut:
            print("==HUB== User signed Out, update UI")
            self.updateUserData(withSignInStatus: false)
    
        case HubPayload.EventName.Auth.sessionExpired:
            print("==HUB== Session expired, show sign in UI")
            self.updateUserData(withSignInStatus: false)
    
        default:
            //print("==HUB== \(payload)")
            break
        }
    }
     
    // let's check if user is signedIn or not
     _ = Amplify.Auth.fetchAuthSession { (result) in
         do {
             let session = try result.get()
                    
    // let's update UserData and the UI
         self.updateUserData(withSignInStatus: session.isSignedIn)
                    
         } catch {
              print("Fetch auth session failed with error - \(error)")
        }
    }    

    c. Atualizar o código de interface de usuário

    A última alteração no código está relacionada à interface de usuário, quando adicionamos um ZStack a ContentView. Dependendo do valor de UserData.isSignedIn, a IU mostra um SigninButton ou a visualização em lista principal.

    Abra o ContentView.swift e substitua o corpo na estrutura ContentView:

    var body: some View {
    
        ZStack {
            if (userData.isSignedIn) {
                NavigationView {
                    List {
                        ForEach(userData.notes) { note in
                            ListRow(note: note)
                        }
                    }
                    .navigationBarTitle(Text("Notes"))
                    .navigationBarItems(leading: SignOutButton())
                }
            } else {
                SignInButton()
            }
        }
    }

    No mesmo arquivo, adicione um SignInButton e uma visualização de SignOutButton:

    struct SignInButton: View {
        var body: some View {
            Button(action: { Backend.shared.signIn() }){
                HStack {
                    Image(systemName: "person.fill")
                        .scaleEffect(1.5)
                        .padding()
                    Text("Sign In")
                        .font(.largeTitle)
                }
                .padding()
                .foregroundColor(.white)
                .background(Color.green)
                .cornerRadius(30)
            }
        }
    }
    
    struct SignOutButton : View {
        var body: some View {
            Button(action: { Backend.shared.signOut() }) {
                    Text("Sign Out")
            }
        }
    }

    Para verificar se tudo funciona conforme o esperado, compile o projeto. Clique no menu Product (Produto) e selecione Build (Compilar) ou digite ⌘B. Não deve aparecer nenhum erro.

    d. Atualizar Info.plist

    Por fim, precisamos assegurar que nosso aplicativo seja iniciado no final da sequência de autenticação da Web, fornecida pela interface de usuário hospedada pelo Cognito. Adicionamos o esquema de URI gettingstarted ao arquivo Info.plist do aplicativo.

    No Xcode, selecione o arquivo Info.plist, clique com o botão direito do mouse nele e selecione Open As, Source Code (Abrir como, Código-fonte).

    iOSTutorial-Module3-step1

    Adicione os elementos <key> e <array> abaixo dentro do elemento <dict> acima.

    <plist version="1.0">
    
        <dict>
        <!-- YOUR OTHER PLIST ENTRIES HERE -->
    
        <!-- ADD AN ENTRY TO CFBundleURLTypes for Cognito Auth -->
        <!-- IF YOU DO NOT HAVE CFBundleURLTypes, YOU CAN COPY THE WHOLE BLOCK BELOW -->
        <key>CFBundleURLTypes</key>
        <array>
            <dict>
                <key>CFBundleURLSchemes</key>
                <array>
                    <string>gettingstarted</string>
                </array>
            </dict>
        </array>
    
        <!-- ... -->
        </dict>

    e. Compilar e testar

    Para verificar se tudo funciona conforme o esperado, compile o projeto. Clique no menu Product (Produto) e selecione Run (Executar) ou digite ⌘R. Não deve aparecer nenhum erro. O aplicativo é iniciado com o botão Sign In (Fazer login).

    Este é o fluxo completo de cadastro:

    iOSTutorial-Module3-step2
    iOSTutorial-Module3-step5
    iOSTutorial-Module3-step3
    iOSTutorial-Module3-step6
    iOSTutorial-Module3-step4
    iOSTutorial-Module3-step7

Conclusão

Você acaba de adicionar a autenticação de usuários ao seu aplicativo, com apenas algumas linhas de código! No próximo módulo, adicionaremos uma API ao aplicativo.

Este módulo foi útil?

Agradecemos a sua atenção
Gostaríamos de saber do que você gostou.
Fechar
Desculpe por ter desapontado
Encontrou algo desatualizado, confuso ou incorreto? Envie seus comentários para nos ajudar a melhorar este tutorial.
Fechar

Adicionar API GraphQL e banco de dados