مكتبة React Native جيدة الكتابة توفر الدعم لمصادقة Apple على نظامي التشغيل iOS وAndroid، بما في ذلك دعم جميع متغيرات AppleButton
.
لن تعمل مكتبة @invertase/react-native-apple-authentication
إذا لم تتأكد مما يلي:
أنت تستخدم الإصدار 0.60
من React Native أو أعلى.
(iOS فقط) لديك بيئة تطوير iOS تفاعلية على جهازك (ستعمل فقط على نظام Mac). إذا لم يكن الأمر كذلك، فيرجى اتباع وثائق React Native الرسمية للبدء: وثائق البدء في React Native.
(iOS فقط) أنت تستخدم الإصدار 11
من Xcode أو أعلى. سيسمح لك هذا بالتطوير باستخدام الإصدار 13
من نظام التشغيل iOS والإصدارات الأحدث، عندما تصبح واجهات برمجة التطبيقات لتسجيل الدخول باستخدام Apple متاحة.
بمجرد التأكد من استيفاء ما ورد أعلاه، يرجى اتباع دليل الإعداد الأولي لبيئة التطوير.
أضاف الإصدار 2 دعم Android وقدم بعض التغييرات العاجلة في كيفية الوصول إلى الطرق. يرجى الاطلاع على دليل الهجرة.
yarn add @invertase/react-native-apple-authentication
(cd ios && pod install)
لن تضطر إلى ربط هذه الوحدة يدويًا لأنها تدعم الارتباط التلقائي لـ React Native.
لتمكين إمكانية تسجيل الدخول باستخدام Apple في تطبيقك، قم بتعيين الخاصية ios.usesAppleSignIn على true في تكوين التطبيق الخاص بمشروعك:
{
"expo" : {
"ios" : {
"usesAppleSignIn" : true
}
}
}
قد تحتاج أيضًا إلى تشغيل npx expo prebuild
.
فيما يلي خطوات بسيطة لمساعدتك على البدء والتشغيل. يختلف التنفيذ بين iOS وAndroid، لذا إذا كنت تواجه مشكلة، فتأكد من الاطلاع على المستندات. يرجى تخطي أمثلة التعليمات البرمجية الكاملة المذكورة أدناه والتوجه إليها إذا كنت تفضل رؤية تنفيذ أكثر اكتمالاً:
React Native Firebase
؛ راجع دليل Firebase الخاص بنا قم باستيراد وحدة appleAuth
(وثائق API) وعنصر العضو المصدر AppleButton
(وثائق API) من مكتبة @invertase/react-native-apple-authentication
. قم بإعداد معالج الأحداث ( onPress
) لبدء طلب المصادقة.
// 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
}
}
قم بإعداد مستمع الأحداث عندما يتم إبطال بيانات اعتماد المستخدم.
// 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 >
) ;
}
توجد عملية appleAuth.Operation.LOGOUT
، إلا أنها لا تعمل كما هو متوقع ولا يتم استخدامها حتى من قبل شركة Apple في رمز المثال الخاص بها. راجع هذه المشكلة لمزيد من المعلومات
لذلك يوصى عند تسجيل الخروج بمسح جميع البيانات التي لديك من المستخدم، والتي تم جمعها أثناء appleAuth.Operation.LOGIN
.
تأكد من تكوين حساب مطور Apple الخاص بك بشكل صحيح للسماح بالمصادقة المناسبة على Android. يمكنك مراجعة دليلنا لمزيد من المعلومات.
// 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
}
تعمل هذه المكتبة على نظام التشغيل MacOS 10.15+ في حالة استخدامها جنبًا إلى جنب مع نظام التشغيل react-native-macos.
yarn add react-apple-signin-auth
مشروع الويب الخاص بك. 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) و appleAuthAndroid.configure
(Android). 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 ,
} ) ;
يتم إنشاء جميع وثائق API بواسطة typedoc، وهي متاحة في مجلد typedocs
لماذا يعود full name
والبريد email
null
؟
full name
والبريد email
فقط عند تسجيل الدخول الأول، وستعيد null
عند تسجيل الدخول التالي، لذا تحتاج إلى حفظ هذه البيانات. 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
، اضغط على تطبيقك، ثم اضغط على Stop Using Apple ID
. يمكنك الآن تسجيل الدخول مرة أخرى وستتلقى full name
والبريد الإلكتروني.email
عن طريق فحص id_token
الذي تم إرجاعه من Apple عند التحقق من المستخدم.كيفية تغيير لغة الزر؟ (آي أو إس)
< key >CFBundleDevelopmentRegion</ key >
< string >en</ string >
< key >CFBundleAllowMixedLocalizations</ key >
< string >true</ string >
كيف أحصل على البريد الإلكتروني بعد تسجيل الدخول الأول؟
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.)
تأكد من أن إعدادات الاتصال قد تم إجراؤها بشكل صحيح. يمكن العثور على الإعداد هنا: الإعداد الأولي
إذا كنت تستخدم الوظيفة getCredentialStateForUser
على جهاز محاكاة، فسيتم دائمًا تشغيل هذا الخطأ، لأن هذه الوظيفة تتحقق من صحة الجهاز.
يجب عليك اختبار الكود الخاص بك على جهاز حقيقي.
إذا كنت تستخدم جهاز محاكاة، فانتقل إلى إدارة حساب Apple.
ابحث عن "الأجهزة"، وحدد "Simulator"، ثم اضغط على "إزالة من الحساب".
يجب أن تعمل بشكل جيد.
"invalid_client" in Android webview
تأكد من قراءة مستندات إعداد خدمات Android.
clientId
الذي قمت بتمريره إلى appleAuthAndroid.configure
لا يتطابق مع معرف الخدمة الذي قمت بإعداده في وحدة تحكم مطور Apple الخاصة بك.
تم إرفاق معرف الخدمة الخاص بك بمعرف التطبيق الأساسي الخاطئ، وبالتالي يستخدم مفتاح تسجيل الدخول باستخدام مفتاح Apple غير الصحيح.
لا يتطابق redirectUri
الذي مررته إلى appleAuthAndroid.configure
مع أحد عناوين URL للإرجاع أو النطاقات/النطاقات الفرعية التي أضفتها في وحدة تحكم مطور Apple. يجب أن يتطابق عنوان URL تمامًا ، ولا يمكن أن يحتوي على سلسلة استعلام.
تم بناؤه وصيانته بواسطة Invertase.