GithubHelp home page GithubHelp logo

Comments (7)

ghonche avatar ghonche commented on August 17, 2024

Hi @Lzolcsi
I'm facing the same issue. any solutions for this?

from apple-sign-in.

Lzolcsi avatar Lzolcsi commented on August 17, 2024

Hi @ghonche ,

at the moment I am going with the following solution:

async appleTokenReceived(event) {
    if(
      typeof event.data !== 'object' ||
      !event.data.hasOwnProperty('appleToken') ||
      !event.data.appleToken
    ) {
      return;
    }
    this.appleSignInAbortController.abort();
    const loadingMessage = await firstValueFrom(this.translate.get('LOADING'));
    this.errorDialog.showLoading(loadingMessage);
    const deviceId = await Device.getId();
    let postData: any = {
      token: event.data.id_token,
      device_name: deviceId.uuid
    };
    if(event.data.hasOwnProperty('name')) {
      postData.name = event.data.name;
    }
    this.http
      .post(environment.apiUrl+'/auth/loginWithApple', postData)
      .subscribe((response: any) => {
        localStorage.setItem('apiToken', response.token);
        this.authService.refreshCurrentUser().then((user: UserModel) => {
          this.errorDialog.hideLoading();
          //REDIRECT user to the main page
        });
      });
  }

  async doAppleLogin() {

    if(Capacitor.getPlatform() === 'web') {
      this.appleSignInAbortController = new AbortController();
      window.open(
        'https://appleid.apple.com/auth/authorize?' +
        'client_id='+environment.appId+'.webapp&' +
        'redirect_uri='+environment.apiUrl+'/auth/signInWithAppleCallback&' +
        'response_type=code id_token&' +
        'scope=name email&' +
        'response_mode=form_post',
        '_blank'
      );
      window.addEventListener('message', e => {this.appleTokenReceived(e)}, {signal: this.appleSignInAbortController.signal});
      return;
    }
    //TODO Make sure this still works on native platform (and possibly android, maybe...)
    const options: SignInWithAppleOptions = {
      clientId: environment.appId+'.webapp',
      redirectURI: '',
      scopes: 'email name',
      state: '12345',
      //nonce: 'nonce',
    };

    const loadingMessage = await firstValueFrom(this.translate.get('LOADING'));
    const deviceId = await Device.getId();
    SignInWithApple.authorize(options)
        .then((result: SignInWithAppleResponse) => {
          this.errorDialog.showLoading(loadingMessage);
          this.http
              .post(environment.apiUrl+'/auth/loginWithApple', {
                token: result.response.identityToken,
                device_name: deviceId.uuid
              })
              .subscribe((response: any) => {
                this.errorDialog.hideLoading();
                localStorage.setItem('apiToken', response.token);
                this.authService.refreshCurrentUser().then((user: UserModel) => {
                  this.errorDialog.hideLoading();
                  this.appComponent.navigateAfterActivated(user, ['purchases']);
                });
              });
        })
        .catch(error => {
          //console.log(error);
        });
  }

This mostly works, at the moment I'm having some trouble figuring out why it doesn't work in dev environment when the domain isn't localhost. But hopefully this is a good starting point for you.
The main trick that solves the window not closing issue is manually opening apples sign in page, but with "response_mode=form_post". This way you can listen to its response message.

from apple-sign-in.

Lzolcsi avatar Lzolcsi commented on August 17, 2024

Unfortunately it seems like this only works on localhost at the moment, the message is not posted back when the domain is something else. I'm having two ideas at the moment:
1: I'll try to use apples own JS framework for the sign in process: https://developer.apple.com/documentation/sign_in_with_apple/sign_in_with_apple_js/configuring_your_webpage_for_sign_in_with_apple
This might have the same issue, but we'll see. Also, I don't want to include Apples JS file for the native apps, so the build process needs to be adjusted for this.
2: The Apple pop up window should post back the credentials in the background to the backend with the state variable, so theoretically if the backend stores the received credentials and the JS client asks the backend with the state variable periodically, it might solve the issue. But this seems to much of a hassle at the moment.

from apple-sign-in.

Lzolcsi avatar Lzolcsi commented on August 17, 2024

Dang, it was so long ago, that I forgot that "localhost" was referenced in my backend as well, that's why only localhost was working. So the catch is that the callback URL should answer with something like this:

        $data = [
            'appleToken' => true,
            'code' => $request -> get('code'),
            'id_token' => $request -> get('id_token')
        ];
        if($request -> has('user')) {
            $user = json_decode($request -> get('user'));
            $data['name'] = $user -> name -> lastName.' '.$user -> name -> firstName;
        }
        //TODO Origin should be working on live server as well
        return response('<html><body><script>
                if (window.opener) {
                    window.opener.postMessage('.json_encode($data).', \'http://localhost:8100/\');
                    window.close();
                }
        </script></body></html>', 200);

the point is: $data should contain the info that you want to pass back to your Ionic app, and obviously localhost should be whatever origin the request really comes from.
So if you add that to the mix, it should work.

In the meantime I was able to make it work with response_mode=web_message as well.

from apple-sign-in.

Lzolcsi avatar Lzolcsi commented on August 17, 2024

Here is a gist for a service provider that works both on ios and web as well:
https://gist.github.com/Lzolcsi/9c275953c63c94f8240d59d04e54507d

I'm closing this because with this everything is working fine for me now.

from apple-sign-in.

viking2917 avatar viking2917 commented on August 17, 2024

I have the same situation; works fine on a device, will not work on the web.

I'm going to try your workaround, but shouldn't this issue remain open? The plugin does not seem to be working correctly on the web?

Has anyone had the recommended code work for them on a website? The documentation suggests it should work 'as is'. ( I have confirmed I haven't made the usual mistakes, my domain is listed without the 'https://' on it, and my redirect_url is https (in fact, it's firebase, so like this: 'https://my-firebase-domain/__/auth/handler')

from apple-sign-in.

viking2917 avatar viking2917 commented on August 17, 2024

For what it's worth, since I'm using Firebase, I just re-coded the web Apple Signin following the Firebase instructions. (e.g. https://firebase.google.com/docs/auth/web/apple#web-version-9), using Javascript and avoiding this plugin. It works fine, although I'd rather not have an extra set of more-or-less duplicate code to maintain.

The main drawback is that I have two different apps with the same backend signin, which doesn't work quite as well with Firebase. Apple Signin uses the Services ID to determine logo and messaging to the user (e.g. "Use your Apple ID to Sign in to App ABC". With this plugin, one can have multiple Apple Service IDs, one for each app, and thus get the correct messaging (what happens for my apps on devices). With Firebase, only one Service ID seems to be allowed, so my second app will show a potentially confusing message mentioning the wrong app....so it would be cool if this plugin could work on the web. (Of course it's possible I'm doing something wrong, but cannot figure what it might be).

from apple-sign-in.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.