一個類型良好的 React Native 庫,提供對 iOS 和 Android 上的 Apple 身份驗證的支持,包括對所有AppleButton
變體的支持。
如果您不確保以下內容@invertase/react-native-apple-authentication
庫將無法運作:
您使用的是 React Native 0.60
或更高版本。
(僅限 iOS)您已在電腦上設定了反應本機 iOS 開發環境(僅適用於 Mac)。如果沒有,請按照 React Native 官方文件入門:React Native 入門文件。
(僅限 iOS)您使用的是 Xcode 版本11
或更高版本。當 Sign In with Apple 的 API 可用時,這將允許您使用 iOS 版本13
及更高版本進行開發。
一旦您確定滿足上述要求,請遵循我們的初始開發環境設定指南。
版本 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 指南從@invertase/react-native-apple-authentication
庫匯入appleAuth
(API 文件)模組和AppleButton
(API 文件)匯出的成員元素。設定事件處理程序 ( 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
}
如果與react-native-macos 結合使用,則該程式庫可在MacOS 10.15+ 上運作。
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
和“電子郵件”。id_token
來存取email
屬性伺服器端。如何更改按鈕語言? (iOS)
< 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 服務設定文件。
您傳遞給appleAuthAndroid.configure
的clientId
與您在 Apple 開發人員控制台中設定的服務 ID 不符。
您的服務 ID 附加到錯誤的主應用程式 ID,因此使用了錯誤的 Apple 金鑰登入。
您傳遞給appleAuthAndroid.configure
redirectUri
與您在 Apple 開發者控制台中新增的返回 URL 或網域/子網域之一不符。 URL 必須完全匹配,且不能包含查詢字串。
由轉化酶建構和維護。