Skip to content

Commit

Permalink
feat(auth): add Sign in with Apple directly in Firebase Auth for Andr…
Browse files Browse the repository at this point in the history
…oid, iOS 13+ and Web (#9408)

* feat(auth): add Sign in with Apple directly in Firebase Auth for Android, iOS 13+ and Web

* feat(auth): add Sign in with Apple directly in Firebase Auth for Android, iOS 13+ and Web

* feat(auth): add Sign in with Apple directly in Firebase Auth for Android, iOS 13+ and Web

* feat(auth): add Sign in with Apple directly in Firebase Auth for Android, iOS 13+ and Web
  • Loading branch information
Lyokone committed Aug 23, 2022
1 parent 1ff76c1 commit da36b98
Show file tree
Hide file tree
Showing 15 changed files with 490 additions and 292 deletions.
113 changes: 25 additions & 88 deletions docs/auth/federated-auth.md
Expand Up @@ -171,98 +171,35 @@ For further information, see this [issue](https://github.com/firebase/flutterfir

## Apple

* {iOS+ and Android}
* {iOS+}

Before you begin [configure Sign In with Apple](/docs/auth/ios/apple#configure-sign-in-with-apple)
and [enable Apple as a sign-in provider](/docs/auth/ios/apple#enable-apple-as-a-sign-in-provider).

Next, make sure that your `Runner` apps have the "Sign in with Apple" capability.

Install the [`sign_in_with_apple`](https://pub.dev/packages/sign_in_with_apple) plugin, as well as the
[`crypto`](https://pub.dev/packages/crypto) package:

```yaml title="pubspec.yaml"
dependencies:
sign_in_with_apple: ^3.0.0
crypto: ^3.0.1
```

```dart
import 'dart:convert';
import 'dart:math';
import 'package:crypto/crypto.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:sign_in_with_apple/sign_in_with_apple.dart';
/// Generates a cryptographically secure random nonce, to be included in a
/// credential request.
String generateNonce([int length = 32]) {
const charset =
'0123456789ABCDEFGHIJKLMNOPQRSTUVXYZabcdefghijklmnopqrstuvwxyz-._';
final random = Random.secure();
return List.generate(length, (_) => charset[random.nextInt(charset.length)])
.join();
}
/// Returns the sha256 hash of [input] in hex notation.
String sha256ofString(String input) {
final bytes = utf8.encode(input);
final digest = sha256.convert(bytes);
return digest.toString();
}
Future<UserCredential> signInWithApple() async {
// To prevent replay attacks with the credential returned from Apple, we
// include a nonce in the credential request. When signing in with
// Firebase, the nonce in the id token returned by Apple, is expected to
// match the sha256 hash of `rawNonce`.
final rawNonce = generateNonce();
final nonce = sha256ofString(rawNonce);
// Request credential for the currently signed in Apple account.
final appleCredential = await SignInWithApple.getAppleIDCredential(
scopes: [
AppleIDAuthorizationScopes.email,
AppleIDAuthorizationScopes.fullName,
],
nonce: nonce,
);
// Create an `OAuthCredential` from the credential returned by Apple.
final oauthCredential = OAuthProvider("apple.com").credential(
idToken: appleCredential.identityToken,
rawNonce: rawNonce,
);
// Sign in the user with Firebase. If the nonce we generated earlier does
// not match the nonce in `appleCredential.identityToken`, sign in will fail.
return await FirebaseAuth.instance.signInWithCredential(oauthCredential);
}
```
* {Android}
Before you begin [configure Sign In with Apple](/docs/auth/android/apple#configure-sign-in-with-apple)
and [enable Apple as a sign-in provider](/docs/auth/android/apple#enable-apple-as-a-sign-in-provider).

* {Web}

Before you begin [configure Sign In with Apple](/docs/auth/web/apple#configure-sign-in-with-apple)
and [enable Apple as a sign-in provider](/docs/auth/web/apple#enable-apple-as-a-sign-in-provider).

```dart
import 'package:firebase_auth/firebase_auth.dart';
Future<UserCredential> signInWithApple() async {
// Create and configure an OAuthProvider for Sign In with Apple.
final provider = OAuthProvider("apple.com")
..addScope('email')
..addScope('name');

// Sign in the user with Firebase.
return await FirebaseAuth.instance.signInWithPopup(provider);
```dart
import 'package:firebase_auth/firebase_auth.dart';
Future<UserCredential> signInWithApple() async {
final appleProvider = AppleAuthProvider();
if (kIsWeb) {
await _auth.signInWithPopup(appleProvider);
} else {
await _auth.signInWithAuthProvider(appleProvider);
}
```

An alternative is to use `signInWithRedirect`. In that case the browser will navigate away from your app
and you have to use `getRedirectResult` to check for authentication results during app startup.

}
```

## Twitter

Expand Down Expand Up @@ -341,20 +278,20 @@ with the Client ID and Secret are set, with the callback URL set in the GitHub a

* {iOS+ and Android}

For native platforms, you need to add the `google-services.json` and `GoogleService-Info.plist`.
For native platforms, you need to add the `google-services.json` and `GoogleService-Info.plist`.

For iOS, add the custom URL scheme as [described on the iOS guide](https://firebase.google.com/docs/auth/ios/github-auth#handle_the_sign-in_flow_with_the_firebase_sdk) step 1.
For iOS, add the custom URL scheme as [described on the iOS guide](https://firebase.google.com/docs/auth/ios/github-auth#handle_the_sign-in_flow_with_the_firebase_sdk) step 1.

```dart
import 'package:github_sign_in/github_sign_in.dart';
```dart
import 'package:github_sign_in/github_sign_in.dart';
Future<UserCredential> signInWithGitHub() async {
// Create a new provider
GithubAuthProvider githubProvider = GithubAuthProvider();
Future<UserCredential> signInWithGitHub() async {
// Create a new provider
GithubAuthProvider githubProvider = GithubAuthProvider();
return await _auth.signInWithAuthProvider(githubProvider);
}
```
return await _auth.signInWithAuthProvider(githubProvider);
}
```

* {Web}

Expand Down
2 changes: 1 addition & 1 deletion packages/firebase_auth/firebase_auth/example/ios/Podfile
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
platform :ios, '10.0'
platform :ios, '13.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 46;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -176,6 +176,7 @@
TargetAttributes = {
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
DevelopmentTeam = YYX2P3XVJ7;
ProvisioningStyle = Automatic;
};
};
Expand Down Expand Up @@ -404,17 +405,15 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = YYX2P3XVJ7;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down Expand Up @@ -540,17 +539,15 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = YYX2P3XVJ7;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand All @@ -571,17 +568,15 @@
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = "";
DEVELOPMENT_TEAM = YYX2P3XVJ7;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
Expand Down
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict/>
<dict>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict>
</plist>

0 comments on commit da36b98

Please sign in to comment.