SwiftHTML & CSSSolidityDesenvolvimento de JogosSolana/Rust
23.11.2024

Aula 118: Autenticação e Segurança em Apps SwiftUI

Nesta aula, vamos explorar os fundamentos da implementação de recursos de autenticação e segurança em aplicações SwiftUI. Como os aplicativos frequentemente lidam com dados sensíveis, é crucial incorporar medidas de segurança para proteger as informações dos usuários. Vamos abordar a autenticação do usuário usando o Firebase como exemplo, além de discutir o uso do Keychain para armazenar dados sensíveis de forma segura.

Configurando a Autenticação do Firebase

Para começar, você precisará configurar o Firebase em seu projeto SwiftUI. Siga estas etapas:

  1. Crie um projeto no Firebase na Console do Firebase.

  2. Adicione seu aplicativo iOS ao projeto fornecendo o Bundle ID.

  3. Faça o download do arquivo GoogleService-Info.plist e adicione-o ao seu projeto no Xcode.

  4. Use o Swift Package Manager para integrar o Firebase Auth ao seu projeto. Adicione a seguinte dependência no Xcode:

    https://github.com/firebase/firebase-ios-sdk.git
  5. Importe o Firebase no seu arquivo App e configure-o:

    import SwiftUI
    import Firebase
    
    @main
    struct SeuApp: App {
       init() {
           FirebaseApp.configure()
       }
       var body: some Scene {
           WindowGroup {
               ContentView()
           }
       }
    }

Cadastro e Login do Usuário

Em seguida, vamos criar uma interface simples para cadastro e login.

Tela de Cadastro

import SwiftUI
import FirebaseAuth

struct TelaDeCadastro: View {
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var mensagemDeErro: String?

    var body: some View {
        VStack {
            TextField("Email", text: $email)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            SecureField("Senha", text: $password)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: cadastrar) {
                Text("Cadastrar")
            }
            .padding()

            if let mensagemDeErro = mensagemDeErro {
                Text(mensagemDeErro)
                    .foregroundColor(.red)
                    .padding()
            }
        }
        .padding()
    }

    private func cadastrar() {
        Auth.auth().createUser(withEmail: email, password: password) { authResult, error in
            if let error = error {
                mensagemDeErro = error.localizedDescription
            } else {
                // Cadastro do usuário bem-sucedido
            }
        }
    }
}

Tela de Login

struct TelaDeLogin: View {
    @State private var email: String = ""
    @State private var password: String = ""
    @State private var mensagemDeErro: String?

    var body: some View {
        VStack {
            TextField("Email", text: $email)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            SecureField("Senha", text: $password)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()

            Button(action: fazerLogin) {
                Text("Fazer Login")
            }
            .padding()

            if let mensagemDeErro = mensagemDeErro {
                Text(mensagemDeErro)
                    .foregroundColor(.red)
                    .padding()
            }
        }
        .padding()
    }

    private func fazerLogin() {
        Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
            if let error = error {
                mensagemDeErro = error.localizedDescription
            } else {
                // Login do usuário bem-sucedido
            }
        }
    }
}

Armazenando Dados Sensíveis de Forma Segura

Ao lidar com dados do usuário, é essencial armazenar as informações sensíveis de forma segura. Uma maneira de fazer isso é usando o Keychain.

Armazenando Dados no Keychain

import Security

class AuxiliarKeychain {
    static func salvarSenha(serviço: String, conta: String, senha: String) {
        let data = senha.data(using: .utf8)!
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: serviço,
            kSecAttrAccount as String: conta,
            kSecValueData as String: data
        ]

        SecItemDelete(query as CFDictionary) // Exclui qualquer item existente
        SecItemAdd(query as CFDictionary, nil) // Adiciona novo item
    }

    static func carregarSenha(serviço: String, conta: String) -> String? {
        let query: [String: Any] = [
            kSecClass as String: kSecClassGenericPassword,
            kSecAttrService as String: serviço,
            kSecAttrAccount as String: conta,
            kSecReturnData as String: true,
            kSecMatchLimit as String: kSecMatchLimitOne
        ]

        var item: CFTypeRef?
        let status = SecItemCopyMatching(query as CFDictionary, &item)

        if status == errSecSuccess, let data = item as? Data {
            return String(data: data, encoding: .utf8)
        }

        return nil
    }
}

Exemplo de Uso

Você pode combinar a Autenticação do Firebase e o Keychain para aumentar a segurança. Por exemplo, após um login bem-sucedido, armazene a senha de forma segura:

private func fazerLogin() {
    Auth.auth().signIn(withEmail: email, password: password) { authResult, error in
        if let error = error {
            mensagemDeErro = error.localizedDescription
        } else {
            // Login do usuário bem-sucedido
            AuxiliarKeychain.salvarSenha(serviço: "SeuApp", conta: email, senha: password)
        }
    }
}

Conclusão

Nesta aula, abordamos o básico da implementação de medidas de autenticação e segurança em uma aplicação SwiftUI usando o Firebase para gerenciamento de usuários e o Keychain para armazenamento seguro de dados. A segurança é um aspecto crítico no desenvolvimento de apps, e incorporar essas práticas ajuda a proteger as informações dos usuários de forma eficaz. Certifique-se de personalizar as telas e o tratamento de erros de acordo com as necessidades do seu aplicativo.

Video

Did you like this article? Rate it from 1 to 5:

Thank you for voting!