Pular para o conteúdo principal
ℹ️ Conteúdo em atualização

Estamos revisando estes procedimentos. Pessoas técnicas podem encontrar ajustes em códigos de erro ou mapeamentos de payload; valide com os logs e o OpenAPI mais recente. Pessoas não técnicas podem continuar usando o passo a passo e acionar o time de suporte caso algo pareça diferente do descrito.

🔐 AllowMe Fingerprint V3

Integração com AllowMe V3 para coleta de fingerprint de dispositivos móveis em aplicativos React Native (Android e iOS).

📋 Visão Geral

O AllowMe é uma solução de segurança que permite identificar dispositivos através de fingerprinting, auxiliando na prevenção de fraudes e autenticação de usuários. A integração V3 suporta nativamente Android e iOS através de bridges React Native.

Funcionalidades

  • ✅ Coleta de fingerprint do dispositivo
  • ✅ Suporte nativo para Android (Kotlin) e iOS (Objective-C)
  • ✅ Integração via React Native Bridge
  • ✅ Inicialização única do SDK
  • ✅ Coleta sob demanda de métricas

🚀 Configuração

Pré-requisitos

  • React Native configurado
  • API Key do AllowMe (solicitar ao time AllowMe)
  • Android Studio (para Android)
  • Xcode (para iOS)
Importante

A API Key é obrigatória e deve ser solicitada diretamente ao time da AllowMe antes de iniciar a integração.


📱 Integração Android

1. Criar Módulo Nativo

Crie a estrutura de pastas e o arquivo do módulo:

android/app/src/main/java/com/[seu-app]/modules/
└── RNAllowMeBridgeModule.kt

2. Implementar Bridge Kotlin

RNAllowMeBridgeModule.kt
package com.seuapp.modules

import android.app.Application
import android.util.Log
import com.facebook.react.bridge.*
import io.allowme.android.AllowMe

class RNAllowMeBridgeModule(reactContext: ReactApplicationContext) :
ReactContextBaseJavaModule(reactContext) {

companion object {
private const val TAG = "RNAllowMeBridge"
private const val ALLOWME_API_KEY = "SUA_API_KEY_AQUI"
}

override fun getName(): String {
return "RNAllowMeBridge"
}

/**
* Inicializa o SDK AllowMe
* Deve ser chamado antes de qualquer coleta
*/
@ReactMethod
fun initSetup(promise: Promise) {
try {
val application = reactApplicationContext.applicationContext as Application
AllowMe.setup(application, ALLOWME_API_KEY)

Log.d(TAG, "AllowMe SDK inicializado com sucesso")
promise.resolve("AllowMe SDK inicializado")
} catch (e: Exception) {
Log.e(TAG, "Erro ao inicializar AllowMe SDK", e)
promise.reject("INIT_ERROR", "Erro ao inicializar AllowMe: ${e.message}", e)
}
}

/**
* Coleta o fingerprint do dispositivo
* Retorna uma string com os dados coletados
*/
@ReactMethod
fun collect(promise: Promise) {
try {
val fingerprint = AllowMe.collect()

if (fingerprint.isNullOrEmpty()) {
promise.reject("COLLECT_ERROR", "Fingerprint vazio ou nulo")
} else {
Log.d(TAG, "Fingerprint coletado com sucesso")
promise.resolve(fingerprint)
}
} catch (e: Exception) {
Log.e(TAG, "Erro ao coletar fingerprint", e)
promise.reject("COLLECT_ERROR", "Erro ao coletar fingerprint: ${e.message}", e)
}
}
}

3. Registrar Módulo no Package

RNAllowMeBridgePackage.kt
package com.seuapp.modules

import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager

class RNAllowMeBridgePackage : ReactPackage {
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
return listOf(RNAllowMeBridgeModule(reactContext))
}

override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList()
}
}

4. Adicionar ao MainApplication

MainApplication.kt
import com.seuapp.modules.RNAllowMeBridgePackage

class MainApplication : Application(), ReactApplication {
override fun getPackages(): List<ReactPackage> {
return PackageList(this).packages.apply {
add(RNAllowMeBridgePackage())
}
}
}

5. Adicionar Dependências Gradle

Build Configurations

Adicione o repositório Maven da AllowMe:

android/build.gradle
allprojects {
repositories {
// ... outros repositórios
maven {
url "https://packagecloud.io/allowme/mobile-fingerprint-android/maven2"
credentials {
username = "YOUR_USERNAME"
password = "YOUR_PASSWORD"
}
}
}
}

Dependências do App

android/app/build.gradle
dependencies {
// ... outras dependências

// AllowMe SDK - Homologação
implementation "io.allowme:android-fingerprint:3.x.x-homolog"

// AllowMe SDK - Produção
// implementation "io.allowme:android-fingerprint:3.x.x"
}
Ambientes
  • Homologação: Use o pacote com sufixo -homolog
  • Produção: Use o pacote sem sufixo

🍎 Integração iOS

1. Estrutura de Arquivos

Crie a estrutura no projeto iOS:

ios/[SeuApp]/Modules/RNAllowMeBridge/
├── RNAllowMeBridge.h
└── RNAllowMeBridge.m

2. Criar Header (.h)

RNAllowMeBridge.h
#import <React/RCTBridgeModule.h>
#import <AllowMe/AllowMe.h>

#define ALLOWME_API_KEY @"SUA_API_KEY_AQUI"

@interface RNAllowMeBridge : NSObject <RCTBridgeModule>
@end

3. Criar Implementation (.m)

RNAllowMeBridge.m
#import "RNAllowMeBridge.h"

@implementation RNAllowMeBridge

RCT_EXPORT_MODULE();

/**
* Inicializa o SDK AllowMe
*/
RCT_REMAP_METHOD(initSetup,
initSetupWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
@try {
[AllowMe setupWithKey:ALLOWME_API_KEY];

NSLog(@"AllowMe SDK inicializado com sucesso");
resolve(@"AllowMe SDK inicializado");
}
@catch (NSException *exception) {
NSLog(@"Erro ao inicializar AllowMe SDK: %@", exception.reason);
reject(@"INIT_ERROR",
[NSString stringWithFormat:@"Erro ao inicializar AllowMe: %@", exception.reason],
nil);
}
}

/**
* Coleta o fingerprint do dispositivo
*/
RCT_REMAP_METHOD(collect,
collectWithResolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
@try {
NSString *fingerprint = [AllowMe collect];

if (fingerprint == nil || [fingerprint length] == 0) {
reject(@"COLLECT_ERROR", @"Fingerprint vazio ou nulo", nil);
} else {
NSLog(@"Fingerprint coletado com sucesso");
resolve(fingerprint);
}
}
@catch (NSException *exception) {
NSLog(@"Erro ao coletar fingerprint: %@", exception.reason);
reject(@"COLLECT_ERROR",
[NSString stringWithFormat:@"Erro ao coletar fingerprint: %@", exception.reason],
nil);
}
}

@end

4. Adicionar ao Build Phases

No Xcode, adicione o arquivo de implementação:

  1. Selecione o target do projeto
  2. Vá em Build Phases
  3. Em Compile Sources, clique no ícone +
  4. Adicione o arquivo RNAllowMeBridge.m

5. Adicionar Pacote AllowMe

Via Swift Package Manager

  1. No Xcode, vá em FileAdd Packages...
  2. Adicione o repositório da AllowMe

Homologação:

https://github.com/allowme/ios-fingerprint-homolog.git

Produção:

https://github.com/allowme/ios-fingerprint.git
  1. Selecione a versão desejada (3.x.x)
  2. Adicione o pacote aos targets necessários
Targets

Adicione o pacote AllowMe em ambos os targets:

  • Target de Homologação
  • Target de Produção

⚛️ Integração React Native

1. Criar Hook Personalizado

hooks/useAllowMeFingerprint.ts
import { NativeModules } from 'react-native';

const { RNAllowMeBridge } = NativeModules;

interface AllowMeFingerprint {
initSetup: () => Promise<string>;
collect: () => Promise<string>;
}

export const useAllowMeFingerprint = (): AllowMeFingerprint => {
/**
* Inicializa o SDK AllowMe
* Deve ser chamado uma única vez no início do fluxo
*/
const initSetup = async (): Promise<string> => {
try {
const result = await RNAllowMeBridge.initSetup();
console.log('[AllowMe] SDK inicializado:', result);
return result;
} catch (error) {
console.error('[AllowMe] Erro ao inicializar SDK:', error);
throw error;
}
};

/**
* Coleta o fingerprint do dispositivo
* Retorna uma string que deve ser enviada ao backend
*/
const collect = async (): Promise<string> => {
try {
const fingerprint = await RNAllowMeBridge.collect();
console.log('[AllowMe] Fingerprint coletado com sucesso');
return fingerprint;
} catch (error) {
console.error('[AllowMe] Erro ao coletar fingerprint:', error);
throw error;
}
};

return {
initSetup,
collect,
};
};

2. Implementar no Componente

screens/LoginScreen.tsx
import React, { useEffect, useState } from 'react';
import { View, Button, Alert } from 'react-native';
import { useAllowMeFingerprint } from '../hooks/useAllowMeFingerprint';

export const LoginScreen: React.FC = () => {
const [isSDKReady, setIsSDKReady] = useState(false);
const { initSetup, collect } = useAllowMeFingerprint();

// Inicializar SDK ao montar componente
useEffect(() => {
const initializeAllowMe = async () => {
try {
await initSetup();
setIsSDKReady(true);
} catch (error) {
Alert.alert('Erro', 'Não foi possível inicializar o AllowMe');
console.error(error);
}
};

initializeAllowMe();
}, []);

const handleLogin = async () => {
if (!isSDKReady) {
Alert.alert('Aguarde', 'SDK ainda não está pronto');
return;
}

try {
// Coletar fingerprint
const fingerprint = await collect();

// Enviar dados de login + fingerprint para o backend
const response = await fetch('https://apihml.credsystem.com.br/auth/login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
username: 'usuario@exemplo.com',
password: 'senha123',
deviceFingerprint: fingerprint, // ← Fingerprint coletado
}),
});

const data = await response.json();

if (response.ok) {
Alert.alert('Sucesso', 'Login realizado com sucesso!');
// Navegar para a próxima tela
} else {
Alert.alert('Erro', data.message || 'Erro ao fazer login');
}
} catch (error) {
Alert.alert('Erro', 'Não foi possível realizar o login');
console.error(error);
}
};

return (
<View>
<Button
title="Fazer Login"
onPress={handleLogin}
disabled={!isSDKReady}
/>
</View>
);
};

3. Exemplo com Context API

contexts/AllowMeContext.tsx
import React, { createContext, useContext, useEffect, useState } from 'react';
import { useAllowMeFingerprint } from '../hooks/useAllowMeFingerprint';

interface AllowMeContextData {
isReady: boolean;
collectFingerprint: () => Promise<string>;
}

const AllowMeContext = createContext<AllowMeContextData>({} as AllowMeContextData);

export const AllowMeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [isReady, setIsReady] = useState(false);
const { initSetup, collect } = useAllowMeFingerprint();

useEffect(() => {
const initialize = async () => {
try {
await initSetup();
setIsReady(true);
} catch (error) {
console.error('[AllowMe] Falha na inicialização:', error);
}
};

initialize();
}, []);

const collectFingerprint = async (): Promise<string> => {
if (!isReady) {
throw new Error('AllowMe SDK ainda não está pronto');
}
return await collect();
};

return (
<AllowMeContext.Provider value={{ isReady, collectFingerprint }}>
{children}
</AllowMeContext.Provider>
);
};

export const useAllowMe = (): AllowMeContextData => {
const context = useContext(AllowMeContext);
if (!context) {
throw new Error('useAllowMe deve ser usado dentro de AllowMeProvider');
}
return context;
};
App.tsx
import React from 'react';
import { AllowMeProvider } from './contexts/AllowMeContext';
import { NavigationContainer } from '@react-navigation/native';
import { Routes } from './routes';

export default function App() {
return (
<AllowMeProvider>
<NavigationContainer>
<Routes />
</NavigationContainer>
</AllowMeProvider>
);
}

🔄 Fluxo de Integração


📊 Casos de Uso

1. Login com Fingerprint

const handleLogin = async (username: string, password: string) => {
const { collectFingerprint } = useAllowMe();

const fingerprint = await collectFingerprint();

await api.post('/auth/login', {
username,
password,
deviceFingerprint: fingerprint,
});
};

2. Transação Financeira

const handleTransaction = async (amount: number) => {
const { collectFingerprint } = useAllowMe();

const fingerprint = await collectFingerprint();

await api.post('/transactions', {
amount,
deviceFingerprint: fingerprint,
timestamp: new Date().toISOString(),
});
};

3. Cadastro de Dispositivo

const registerDevice = async () => {
const { collectFingerprint } = useAllowMe();

const fingerprint = await collectFingerprint();

await api.post('/devices/register', {
deviceFingerprint: fingerprint,
deviceInfo: {
platform: Platform.OS,
version: Platform.Version,
},
});
};

⚠️ Tratamento de Erros

const collectWithErrorHandling = async () => {
const { isReady, collectFingerprint } = useAllowMe();

try {
if (!isReady) {
throw new Error('SDK não inicializado');
}

const fingerprint = await collectFingerprint();

if (!fingerprint || fingerprint.length === 0) {
throw new Error('Fingerprint vazio');
}

return fingerprint;
} catch (error) {
if (error.code === 'INIT_ERROR') {
console.error('Erro de inicialização do SDK');
// Tentar reinicializar
} else if (error.code === 'COLLECT_ERROR') {
console.error('Erro ao coletar dados do dispositivo');
// Usar fallback ou reportar
} else {
console.error('Erro desconhecido:', error);
}

throw error;
}
};

🔧 Troubleshooting

Android

Problema: AllowMe class not found

Solução: Verifique se o repositório Maven foi adicionado corretamente
e se a dependência está sincronizada.

Problema: Module RNAllowMeBridge not registered

Solução: Certifique-se de ter adicionado o RNAllowMeBridgePackage 
ao getPackages() no MainApplication.

iOS

Problema: Module RNAllowMeBridge requires main queue setup

Solução: Adicione + (BOOL)requiresMainQueueSetup { return YES; }
no arquivo RNAllowMeBridge.m

Problema: AllowMe framework not found

Solução: Verifique se o pacote foi adicionado corretamente
aos targets do projeto no Xcode.

📚 Referências

  • 📖 Documentação Oficial: Solicitar ao time AllowMe
  • 🔐 Segurança: Manter API Key em variáveis de ambiente
  • 🧪 Testes: Usar ambiente de homologação antes de produção

💡 Boas Práticas

  1. ✅ Inicialize o SDK uma única vez no ciclo de vida do app
  2. ✅ Sempre valide se o SDK está pronto antes de coletar
  3. ✅ Use Context API ou Redux para gerenciar o estado global
  4. ✅ Implemente retry logic para falhas temporárias
  5. ✅ Nunca exponha a API Key no código versionado
  6. ✅ Use variáveis de ambiente para diferentes ambientes
  7. ✅ Implemente logging adequado para debugging
  8. ✅ Teste em dispositivos físicos (emuladores podem ter limitações)