aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.42k stars 2.12k forks source link

Support Sign In With Apple, Required for Apps using Social Sign In #3395

Closed cliffordh closed 4 years ago

cliffordh commented 5 years ago

Is your feature request related to a problem? Please describe. On Jun 3rd, Apple announced a new feature called Sign In With Apple. It is a social sign in solution similar to Facebook and Google Sign In. However, Sign In with Apple now lets the user decide what, if any personal information such as email, is shared with the developer. The user may choose to have an email alias sent to the developer instead of their real email address.

IMPORTANT "Sign In with Apple will be available for beta testing this summer. It will be required as an option for users in apps that support third-party sign-in when it is commercially available later this year." https://developer.apple.com/news/?id=06032019j

Apps that use social sign in but fail to implement Sign In with Apple will be rejected.

Describe the solution you'd like Add Sign In with Apple to Amplify, Cognito and Hosted UI.

jclough96 commented 5 years ago

As this is a requirement from Apple, could we also get some feedback as too when this is likely to be implemented for Hosted UI and/or Amplify. We currently rely on the Hosted UI for Cognito authorisation in our iOS apps and would need to test. Thanks for raising the issue @cliffordh

damianesteban commented 5 years ago

This feature is absolutely necessary for us if we are going to continue to use Cognito. Auth0 has already released a solution. I understand that their sole focus is identity, but I think it’s reasonable to ask that Cognito have support for Apple OAuth by mid-September. Is there any update on this?

Thanks.

anthonycmain commented 5 years ago

+1 we need this urgently otherwise we will not be able to publish apps using Cognito

koxon commented 5 years ago

Yes, what is the status on this for both Federated Identities and User Pool ?

If Apple is not fully openID compatible, Cognito will certainly reject it ..

palpatim commented 5 years ago

@sarahcec Can you provide an update on this?

sarahcec commented 5 years ago

Hi all, I'm the PM for Amazon Cognito, which is the service that Amplify uses to provide authentication. Thanks for the feedback. We're glad that you're excited about implementing Sign In with Apple. We're excited too. We are working with Apple closely to make sure that Amazon Cognito customers will have this feature available before Apple requires it in April 2020.

thomasvsundert commented 5 years ago

@sarahcec the April 2020 deadline is only for existing apps and updates, new apps need to comply to the new guidelines already today. What are our options?

jdrobert commented 4 years ago

@sarahcec It has been over 3 weeks since the last response. Can we get an update on this?

Our app is set to launch sometime this month. It would be nice to know how I need handle social login.

bastianbb commented 4 years ago

We are almost ready to put our app on the Apple App Store, this is the only thing that is blocking us. An alternative is to setup the signin/signup with a User Pool alongside socials, so you can avoid adding Apple Sign in but we don’t want to maintain a pool.

olivoil commented 4 years ago

@bastianbb that might not be a viable alternative according to the clarification in this TechCrunch article. It states that in the case of apps that use a social sign on service as well as their own sign on service, they must offer Sign in with Apple as well.

So adding a user pool alongside socials won’t work according to them.

phcorp commented 4 years ago

FYI expo integrated Apple sign-in https://github.com/expo/expo/blob/master/docs/pages/versions/unversioned/sdk/apple-authentication.md

bastianbb commented 4 years ago

@bastianbb that might not be a viable alternative according to the clarification in this TechCrunch article. It states that in the case of apps that use a social sign on service as well as their own sign on service, they must offer Sign in with Apple as well.

So adding a user pool alongside socials won’t work according to them.

@olivoil before writing my comment i gave a read to Apple Store Review Guidelines, in particular at 4.8 they begin with: "Apps that exclusively use a third-party or social login service (such as Facebook Login, Google Sign-In, Sign in with Twitter, Sign In with LinkedIn, Login with Amazon, or WeChat Login) to set up or authenticate the user’s primary account with the app must also offer Sign in with Apple as an equivalent option." After reading this, I personally contacted the Apple Support and they confirmed that if I have my own authentication system (e.g Cognito User Pool), i can add Social Providers sign in avoiding the Apple Sign in option.

chefren commented 4 years ago

In case Apple changes their mind: https://medium.com/@farasath/sign-in-with-apple-a-zero-code-change-approach-54b44d59f60c Could use OIDC (it's more expensive in Cognito, but another option)

sarahcec commented 4 years ago

Thanks for waiting out the suspense, everyone. This feature is now live! https://aws.amazon.com/about-aws/whats-new/2019/11/amazon-cognito-now-supports-sign-in-with-apple/

mthormann-dhi commented 4 years ago

Awesome news! Will the documentation at https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-federation-with-social-idp.html be updated soon as well? Still just see Amazon, FB, and Google.

sarahcec commented 4 years ago

Our doc writers are working on an issue. Our apoligies! Developer guide should be updated in about two hours.

Saravanakumar22 commented 4 years ago

Still, I couldn't find the identity provider for 'Sign in with Apple' like facebook (AWSIdentityProviderFacebook) for custom sign in. AWS version: 2.12.2

if anyone has done this, please help me

Thanks in advance

markmckim commented 4 years ago

I have successfully got this working, the identity provider name is "SignInWithApple". So far everything is working as expected for me

Saravanakumar22 commented 4 years ago

@markmckim is there any docs for signInWithApple?. can you please share your code?

markmckim commented 4 years ago

Some of the documentation (for configuring via the console) is covered here: https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-configuring-federation-with-social-idp.html

I was setting this up via a CFT Custom Resource so some of the api docs hadn't been updated so it was a bit of trial and error but I got there in the end

Saravanakumar22 commented 4 years ago

Thank you @markmckim. do you have iOS code for the SignInWithApple ?

markmckim commented 4 years ago

Unfortunately not, mine is a React Native app so it's all Javascript. From the app-side it was just a single one-line function call to the Amplify.Auth package...

Auth.federatedSignIn({ provider: 'SignInWithApple' }))

Saravanakumar22 commented 4 years ago

Thank you @markmckim

iamdavidmartin commented 4 years ago

Here's how to use apple with the HostedUI withOAuth. You're used to seeing these props:

const { oAuthUser: user, oAuthError: error, hostedUISignIn, facebookSignIn, googleSignIn, signOut, loading } = oauthProps;

Note that there is no appleSignIn. Solution: import import { Auth } from "aws-amplify";

And create a button, onPress is ()=>Auth.federatedSignIn({ provider: "SignInWithApple" });

Thanks to @markmckim!

Saravanakumar22 commented 4 years ago

Anyone have done SignIn with Apple for iOS in swift?

lazy-var commented 4 years ago

@Saravanakumar22 you can try with adapting the following code (HostedUI) to your use case:

let hostedUIOptions = HostedUIOptions(/*scopes: ["openid", "email", "name", "phone", "aws.cognito.signin.user.admin", "profile"],*/ identityProvider: "SignInWithApple")

let dropInView = UINavigationController(rootViewController: UIViewController())

AWSMobileClient.default().showSignIn(navigationController: dropInView, hostedUIOptions: hostedUIOptions) { (userState, error) in
            if let error = error as? AWSMobileClientError {
                print("TRACE: - \(#function)@\(#file) (\(#line):\(#column)): sharedInstance().showSignIn error: \(error) [\(error.localizedDescription)].")
            }
            if let userState = userState {
                print("TRACE: - \(#function)@\(#file) (\(#line):\(#column)): sharedInstance().showSignIn userState: \(userState.rawValue).")
                DispatchQueue.main.async {

                }
            }
        }

I couldn't manage to make it work by restricting scopes, so I'm calling the function without defined scopes.

Also, I am not getting user's email nor name.

Saravanakumar22 commented 4 years ago

@Soek22 For Custom login UI using AWS. do you have any suggestions?

iamdavidmartin commented 4 years ago

@markmckim quick follow up to my reply above: I use the withOauth HOC which means I don't need to manage refreshing tokens. But now, with apple not being part of the HOC, I'm using the approach I mentioned before:

()=>Auth.federatedSignIn({ provider: "SignInWithApple" });

Are you managing the refresh tokens as described here? https://aws-amplify.github.io/docs/js/authentication#token-refresh

markmckim commented 4 years ago

@iamdavidmartin - I don't have any custom code for handling refresh tokens...it just seems to work out of the box. My guess is that Amplify is handling it out of the box because all my API calls and auth calls all go through the amplify package.

iamdavidmartin commented 4 years ago

@markmckim it's working for me as well, but I'm not sure what happens when the tokens expire. Nor do I actually know how long they last before they expire...

Thanks for the reply 😀

haverchuck commented 4 years ago

@iamdavidmartin I believe the token expiration is dictated by the User Pool configuration (not to be confused with the actual AWS credentials that are provisioned with the aid of the tokens - these are more shortlived).

haverchuck commented 4 years ago

Closing this issue as this issue as the feature has been implemented in Hosted UI and is handled by Amplify. We do have an open issue concerning Sign In With Apple... if anyone experiences this behavior or has other problems regarding the feature, please respond to this issue or post a new one.

iamdavidmartin commented 4 years ago

Hi @haverchuck, I see you closed this, but is the implementation finished? Specifically, the amplify withOAuth HOC does not support sign in with Apple.

In the docs (https://aws-amplify.github.io/docs/js/authentication#react-components) there are 3 providers that are supported:

I believe this HOC ought to have another prop:

Does that make sense? Otherwise we're implementing Apple differently from all the other providers (code described in previous comments), and with less confidence that it will behave the same way.

iamdavidmartin commented 4 years ago

@haverchuck one other thing, the HOC also supports a variable called "loading" which we use to let our users know that processing is happening during auth, we show a spinner. But since the HOC doesn't support Sign In With Apple, the loading variable isn't available and the UI appears frozen as the hosted UI is presented.

So, another reason why HOC support for sign in with apple would be nice is to support that loading variable which would improve the UI and make it function consistently with the other federated auth methods.

danielbalderas commented 4 years ago

Any update?

I have same problem but I can have a solution, I'm trying with this documentation:

The result is negative, if I try to login but apple doesn't respond to cognito, the problem that I have is:

When I authenticated with apple I got the url:

https://appleid.apple.com/auth/authorize?client_id=XXXXXX&redirect_uri=https%3A%2F%2FDOMAIN.auth.us-west-2.amazoncognito.com%2Foauth2%2Fidpresponse&scope=email+name&response_mode=form_post&response_type=code&state=XXXXXXX

but doesn't redirect to /oauth/idprespond it keep it on https://appleid.apple.com/auth/authorize?...

I hope someone else can help us.

zipper1972 commented 4 years ago

SignIn with Apple at the User Pool level is useless for me (we're not web, we're mobile only), using Unity (iOS/Android). I need this functionality at the Identity Pool level as it is with Facebook and Google. Looks like I'm going to have to leverage OpenID, or perhaps proxy through CogIDP to CogUP, as CogIDP supports User Pool as an identity source... Or, convert the Amplify code to C# (for Unity)... Any suggestions here? Or, thinking about it more, use the Unity Asset for SignIn with Apple (here: https://assetstore.unity.com/packages/tools/sign-in-with-apple-154202?_ga=2.178867748.1663343842.1580442794-1791708539.1580442794) and use a CogIDP with UnAuthenticated identities enabled, as identities are just performing invoke-api calls anyway (Just need the IDP to vend AWS creds for Signed Requests(SigV4)).... Any-who, suggestions from the audience would be much appreciated... Thanks in advance!

mezalejandro commented 4 years ago

Could anyone solve this?

irwansyahnri commented 4 years ago

Here is the solution: https://medium.com/@irwansyah/supporting-sign-in-with-apple-in-aws-amplify-8fdba766a4a

mezalejandro commented 4 years ago

Hi @irwansyahnri thanks for your article, before I had this:

const loginApple = await Auth.federatedSignIn('SignInWithApple', {token: data.identityToken, expires_at: null},data)

And now I changed for this: const userApple = await Auth.federatedSignIn({provider: "SignInWithApple" }, {token: data.identityToken, expires_at: null},data)

Now I have this error: TypeError: Cannot read property 'redirectSignIn' of undefined

Thanks

amerida63 commented 4 years ago

Anything new with the login functionality with apple at the User Pool level, I'm trying to implement it with Swift, (Mobile only). I have configured the entire environment but it does not work.

I really don't know if I have to update the awsconfiguration.json (but every time I generate it, it doesn't update it for me) I don't know what apple keys should I put it, if anyone can help me it would be great.

I am trying to use the same approach that I use for google and facebook, but the

getIdentityId()

function always fails.

I will leave here the code of what I am trying to do, see if my info is incorrect and can help me.

` 
// identityProvider ="SignInWithApple"  I have also tried  "appleid.apple.com"
// accesToken = "appleIDCredential.identityToken" I use the one that returns the login with apple

AWSMobileClient.default().federatedSignIn(providerName: identityProvider, token: accesToken) { (userState, error)  in

            guard error == nil, let userState = userState else {
                completion(false)
                return
            }
            switch userState {
            case .signedOut, .signedOutFederatedTokensInvalid, .signedOutUserPoolsTokenInvalid, .guest, .unknown:
                completion(false)
                return
            // Now we are signed in we need to check whether this is really a new user or not
            case .signedIn:
                completion(true)
          //This function always returns me correctly, and indicates that the session is started.
            }
        }

//But when call this function. 
 let identityTask: AWSTask = AWSMobileClient.default().getIdentityId()

 override public func getIdentityId() -> AWSTask<NSString> {
        guard self.internalCredentialsProvider != nil else {
            return AWSTask(error: AWSMobileClientError.cognitoIdentityPoolNotConfigured(message: "Cannot get identityId since cognito credentials configuration is not available."))
        }
        let identityFetchTaskCompletionSource: AWSTaskCompletionSource<NSString> = AWSTaskCompletionSource()
        self.internalCredentialsProvider?.getIdentityId().continueWith(block: { (task) -> Any? in
            if let error = task.error {
                if error._domain == AWSCognitoCredentialsProviderHelperErrorDomain
                    && error._code == AWSCognitoCredentialsProviderHelperErrorType.identityIsNil.rawValue {

 All the time it enters here, so it does not return a valid result.

                    identityFetchTaskCompletionSource.set(error: AWSMobileClientError.identityIdUnavailable(message: "Fetching identity id on another thread failed. Please retry by calling `getIdentityId()` method."))
                } else {
                    identityFetchTaskCompletionSource.set(error: error)
                }
            } else if let result = task.result {
                identityFetchTaskCompletionSource.set(result: result)
            }
            return nil
        })

        return identityFetchTaskCompletionSource.task
    }
`
github-actions[bot] commented 3 years ago

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.