Une bibliothèque React Native bien typée prenant en charge l'authentification Apple sur iOS et Android, y compris la prise en charge de toutes les variantes AppleButton
.
La bibliothèque @invertase/react-native-apple-authentication
ne fonctionnera pas si vous ne garantissez pas ce qui suit :
Vous utilisez React Native version 0.60
ou supérieure.
(iOS uniquement) Vous avez configuré un environnement de développement iOS réactif natif sur votre ordinateur (ne fonctionnera que sur Mac). Sinon, veuillez suivre la documentation officielle de React Native pour commencer : Documentation de démarrage de React Native.
(iOS uniquement) Vous utilisez Xcode version 11
ou supérieure. Cela vous permettra de développer en utilisant iOS version 13
et supérieure, lorsque les API de connexion avec Apple seront disponibles.
Une fois que vous êtes sûr d'avoir respecté les conditions ci-dessus, veuillez suivre notre guide de configuration initiale de l'environnement de développement.
La version 2 a ajouté la prise en charge d'Android et a introduit quelques modifications majeures dans la façon dont les méthodes sont accessibles. Veuillez consulter le Guide de migration.
yarn add @invertase/react-native-apple-authentication
(cd ios && pod install)
Vous n'aurez pas à lier manuellement ce module car il prend en charge la liaison automatique React Native.
Pour activer la fonctionnalité Se connecter avec Apple dans votre application, définissez la propriété ios.usesAppleSignIn sur true dans la configuration de l'application de votre projet :
{
"expo" : {
"ios" : {
"usesAppleSignIn" : true
}
}
}
Vous devrez peut-être également exécuter npx expo prebuild
.
Vous trouverez ci-dessous des étapes simples pour vous aider à être opérationnel. L'implémentation diffère entre iOS et Android, donc si vous rencontrez des problèmes, assurez-vous de consulter la documentation. Veuillez passer aux exemples de code complets ci-dessous si vous préférez voir une implémentation plus complète :
React Native Firebase
; voir notre guide Firebase Importez le module appleAuth
(documentation API) et l'élément membre exporté AppleButton
(documentation API) à partir de la bibliothèque @invertase/react-native-apple-authentication
. Configurez un gestionnaire d'événements ( onPress
) pour lancer la demande d'authentification.
// App.js
import React from 'react' ;
import { View } from 'react-native' ;
import { AppleButton } from '@invertase/react-native-apple-authentication' ;
async function onAppleButtonPress ( ) {
}
function App ( ) {
return (
< View >
< AppleButton
buttonStyle = { AppleButton . Style . WHITE }
buttonType = { AppleButton . Type . SIGN_IN }
style = { {
width : 160 , // You must specify a width
height : 45 , // You must specify a height
} }
onPress = { ( ) => onAppleButtonPress ( ) }
/ >
< / View >
) ;
}
// App.js
import { appleAuth } from '@invertase/react-native-apple-authentication' ;
async function onAppleButtonPress ( ) {
// performs login request
const appleAuthRequestResponse = await appleAuth . performRequest ( {
requestedOperation : appleAuth . Operation . LOGIN ,
// Note: it appears putting FULL_NAME first is important, see issue #293
requestedScopes : [ appleAuth . Scope . FULL_NAME , appleAuth . Scope . EMAIL ] ,
} ) ;
// get current authentication state for user
// /! This method must be tested on a real device. On the iOS simulator it always throws an error.
const credentialState = await appleAuth . getCredentialStateForUser ( appleAuthRequestResponse . user ) ;
// use credentialState response to ensure the user is authenticated
if ( credentialState === appleAuth . State . AUTHORIZED ) {
// user is authenticated
}
}
Configurez un écouteur d'événements lorsque les informations d'identification de l'utilisateur ont été révoquées.
// App.js
import React , { useEffect } from 'react' ;
import { View } from 'react-native' ;
import { appleAuth , AppleButton } from '@invertase/react-native-apple-authentication' ;
function App ( ) {
useEffect ( ( ) => {
// onCredentialRevoked returns a function that will remove the event listener. useEffect will call this function when the component unmounts
return appleAuth . onCredentialRevoked ( async ( ) => {
console . warn ( 'If this function executes, User Credentials have been Revoked' ) ;
} ) ;
} , [ ] ) ; // passing in an empty array as the second argument ensures this is only ran once when component mounts initially.
return (
< View >
< AppleButton onPress = { ( ) => onAppleButtonPress ( ) } / >
< / View >
) ;
}
Il existe une opération appleAuth.Operation.LOGOUT
, mais elle ne fonctionne pas comme prévu et n'est même pas utilisée par Apple dans son exemple de code. Voir ce problème pour plus d'informations
Il est donc recommandé lors de la déconnexion d'effacer simplement toutes les données dont vous disposez auprès d'un utilisateur, collectées lors de appleAuth.Operation.LOGIN
.
Assurez-vous de configurer correctement votre compte développeur Apple pour permettre une authentification appropriée sur Android. Vous pouvez consulter notre guide pour plus d’informations.
// App.js
import React from 'react' ;
import { View } from 'react-native' ;
import { appleAuthAndroid , AppleButton } from '@invertase/react-native-apple-authentication' ;
async function onAppleButtonPress ( ) {
}
// Apple authentication requires API 19+, so we check before showing the login button
function App ( ) {
return (
< View >
{ appleAuthAndroid . isSupported && (
< AppleButton
buttonStyle = { AppleButton . Style . WHITE }
buttonType = { AppleButton . Type . SIGN_IN }
onPress = { ( ) => onAppleButtonPress ( ) }
/ >
) }
< / View >
) ;
}
// App.js
import { appleAuthAndroid } from '@invertase/react-native-apple-authentication' ;
import 'react-native-get-random-values' ;
import { v4 as uuid } from 'uuid'
async function onAppleButtonPress ( ) {
// Generate secure, random values for state and nonce
const rawNonce = uuid ( ) ;
const state = uuid ( ) ;
// Configure the request
appleAuthAndroid . configure ( {
// The Service ID you registered with Apple
clientId : 'com.example.client-android' ,
// Return URL added to your Apple dev console. We intercept this redirect, but it must still match
// the URL you provided to Apple. It can be an empty route on your backend as it's never called.
redirectUri : 'https://example.com/auth/callback' ,
// The type of response requested - code, id_token, or both.
responseType : appleAuthAndroid . ResponseType . ALL ,
// The amount of user information requested from Apple.
scope : appleAuthAndroid . Scope . ALL ,
// Random nonce value that will be SHA256 hashed before sending to Apple.
nonce : rawNonce ,
// Unique state value used to prevent CSRF attacks. A UUID will be generated if nothing is provided.
state ,
} ) ;
// Open the browser window for user sign in
const response = await appleAuthAndroid . signIn ( ) ;
// Send the authorization code to your backend for verification
}
Cette bibliothèque fonctionne sur MacOS 10.15+ si elle est utilisée conjointement avec React-native-macos.
yarn add react-apple-signin-auth
dans votre projet Web. import AppleSignin from 'react-apple-signin-auth' ;
/** Apple Signin button */
const MyAppleSigninButton = ( { ... rest } ) => (
< AppleSignin
/** Auth options passed to AppleID.auth.init() */
authOptions = { {
clientId : 'SAME AS ANDROID' ,
redirectURI : 'SAME AS ANDROID' ,
scope : 'email name' ,
state : 'state' ,
/** sha256 nonce before sending to apple to unify with native firebase behavior - https://github.com/invertase/react-native-apple-authentication/issues/28 */
nonce : sha256 ( 'nonce' ) ,
/** We have to usePopup since we need clientSide authentication */
usePopup : true ,
} }
onSuccess = { ( response ) => {
console . log ( response ) ;
// {
// "authorization": {
// "state": "[STATE]",
// "code": "[CODE]",
// "id_token": "[ID_TOKEN]"
// },
// "user": {
// "email": "[EMAIL]",
// "name": {
// "firstName": "[FIRST_NAME]",
// "lastName": "[LAST_NAME]"
// }
// }
// }
} }
/ >
) ;
export default MyAppleSigninButton ;
appleAuth.performRequest
(iOS) et appleAuthAndroid.configure
(Android) est automatiquement haché en SHA256. crypto . createHash ( 'sha256' ) . update ( nonce ) . digest ( 'hex' ) ;
import crypto from 'crypto' ;
import appleSigninAuth from 'apple-signin-auth' ;
appleIdTokenClaims = await appleSigninAuth . verifyIdToken ( id_token , {
/** sha256 hex hash of raw nonce */
nonce : nonce ? crypto . createHash ( 'sha256' ) . update ( nonce ) . digest ( 'hex' ) : undefined ,
} ) ;
Toute la documentation de l'API est générée par typedoc et est disponible dans le dossier typedocs
Pourquoi full name
et email
renvoient-ils null
?
full name
et email
lors de la première connexion, il renverra null
lors de la connexion suivante, vous devez donc enregistrer ces données. const appleAuthRequestResponse = await appleAuth . performRequest ( {
requestedOperation : appleAuth . Operation . LOGIN ,
requestedScopes : [ appleAuth . Scope . FULL_NAME , appleAuth . Scope . EMAIL ] ,
} ) ;
Settings > Apple ID, iCloud, iTunes & App Store > Password & Security > Apps Using Your Apple ID
, appuyez sur votre application et appuyez sur Stop Using Apple ID
. Vous pouvez maintenant vous reconnecter et vous recevrez le full name
et l'adresse e-mail.email
côté serveur en inspectant le id_token
renvoyé par Apple lors de la vérification de l'utilisateur.Comment changer la langue des boutons ? (iOS)
< key >CFBundleDevelopmentRegion</ key >
< string >en</ string >
< key >CFBundleAllowMixedLocalizations</ key >
< string >true</ string >
Comment puis-je recevoir l'e-mail après la première connexion ?
import { appleAuth } from '@invertase/react-native-apple-authentication' ;
import { jwtDecode } from 'jwt-decode' ;
const appleAuthRequestResponse = await appleAuth . performRequest ( {
requestedOperation : appleAuth . Operation . LOGIN ,
requestedScopes : [ appleAuth . Scope . EMAIL , appleAuth . Scope . FULL_NAME ]
} ) ;
// other fields are available, but full name is not
const { email , email_verified , is_private_email , sub } = jwtDecode ( appleAuthRequestResponse . identityToken )
The operation couldn’t be completed. (com.apple.AuthenticationServices.AuthorizationError error 1000.)
Vérifiez que les paramètres de connexion ont été correctement définis. La configuration peut être trouvée ici : Configuration initiale
Si vous utilisez la fonction getCredentialStateForUser
sur un simulateur, cette erreur sera toujours déclenchée, car cette fonction vérifie l'authenticité de l'appareil.
Vous devez tester votre code sur un appareil réel.
Si vous utilisez un simulateur, accédez à Gérer le compte Apple.
Recherchez « Appareils », sélectionnez « Simulateur » et appuyez sur « Supprimer du compte ».
Cela devrait bien fonctionner.
"invalid_client" in Android webview
Assurez-vous de lire les documents de configuration des services Android.
Le clientId
que vous avez transmis à appleAuthAndroid.configure
ne correspond pas à l'ID de service que vous avez configuré dans votre console de développement Apple.
Votre ID de service est associé au mauvais ID d’application principal et utilise donc une clé de connexion avec Apple incorrecte.
Le redirectUri
que vous avez transmis à appleAuthAndroid.configure
ne correspond pas à l'une des URL de retour ou des domaines/sous-domaines que vous avez ajoutés dans votre console de développement Apple. L'URL doit correspondre exactement et ne peut pas contenir de chaîne de requête.
Construit et entretenu par Invertase.