ไลบรารี React Native ที่พิมพ์อย่างดีซึ่งให้การสนับสนุน Apple Authentication บน iOS และ Android รวมถึงรองรับ AppleButton
ทุกรูปแบบ
ไลบรารี @invertase/react-native-apple-authentication
จะไม่ทำงานหากคุณไม่มั่นใจสิ่งต่อไปนี้:
คุณกำลังใช้ React Native เวอร์ชัน 0.60
หรือสูงกว่า
(iOS เท่านั้น) คุณได้ตั้งค่าสภาพแวดล้อมการพัฒนา iOS แบบตอบสนองดั้งเดิมบนเครื่องของคุณ (ใช้งานได้บน Mac เท่านั้น) หากไม่เป็นเช่นนั้น โปรดปฏิบัติตามเอกสารประกอบการเริ่มต้นใช้งาน React Native อย่างเป็นทางการ: เอกสารการเริ่มต้นใช้งาน React Native
(iOS เท่านั้น) คุณกำลังใช้ Xcode เวอร์ชัน 11
ขึ้นไป สิ่งนี้จะช่วยให้คุณสามารถพัฒนาโดยใช้ iOS เวอร์ชัน 13
และสูงกว่าได้ เมื่อ API สำหรับการลงชื่อเข้าใช้ด้วย 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) จะถูกแฮช 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 ,
} ) ;
เอกสารประกอบ 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
ค้นหา "อุปกรณ์" เลือก "จำลอง" และกด "ลบออกจากบัญชี"
มันควรจะทำงานได้ดี
"invalid_client" in Android webview
อย่าลืมอ่านเอกสารการตั้งค่าบริการ Android
clientId
ที่คุณส่งไปยัง appleAuthAndroid.configure
ไม่ตรงกับรหัสบริการที่คุณตั้งค่าในคอนโซลนักพัฒนาซอฟต์แวร์ของ Apple
รหัสบริการของคุณแนบอยู่กับรหัสแอปหลักที่ไม่ถูกต้อง ดังนั้นจึงใช้การลงชื่อเข้าใช้ด้วยรหัส Apple ที่ไม่ถูกต้อง
redirectUri
ที่คุณส่งไปยัง appleAuthAndroid.configure
ไม่ตรงกับหนึ่งใน URL ที่ส่งคืนหรือโดเมน/โดเมนย่อยที่คุณเพิ่มในคอนโซลนักพัฒนาซอฟต์แวร์ของ Apple URL ต้องตรงกัน ทุกประการ และต้องไม่มีสตริงข้อความค้นหา
สร้างและบำรุงรักษาโดย Invertase