Coder Social home page Coder Social logo

a-tokyo / react-apple-signin-auth Goto Github PK

View Code? Open in Web Editor NEW
98.0 4.0 13.0 932 KB

 Apple signin for React using the official Apple JS SDK

Home Page: https://a-tokyo.github.io/react-apple-signin-auth

License: MIT License

JavaScript 100.00%
apple signin login auth authentication react vue react-apple apple-js apple-sdk

react-apple-signin-auth's Introduction

react-apple-signin-auth

 Apple signin for React using the official Apple JS SDK

Follow @ahmad_tokyo

Checkout the demo for a quick start!

Prerequisites

  1. You should be enrolled in Apple Developer Program.
  2. Please have a look at Apple documentation related to "Sign in with Apple" feature.
  3. You should create App ID and Service ID in your Apple Developer Account.
  4. You should generate private key for your Service ID in your Apple Developer Account.

Apple Signin Setup

Deatiled confuguration instructions can be found at blog post and Apple docs and official apple docs for webpage signin.

Installation

npm i react-apple-signin-auth

OR

yarn add react-apple-signin-auth

Usage

Checkout the demo for a quick start!

import AppleSignin from 'react-apple-signin-auth';

/** Apple Signin button */
const MyAppleSigninButton = () => (
  <AppleSignin
    /** Auth options passed to AppleID.auth.init() */
    authOptions={{
      /** Client ID - eg: 'com.example.com' */
      clientId: 'com.example.web',
      /** Requested scopes, seperated by spaces - eg: 'email name' */
      scope: 'email name',
      /** Apple's redirectURI - must be one of the URIs you added to the serviceID - the undocumented trick in apple docs is that you should call auth from a page that is listed as a redirectURI, localhost fails */
      redirectURI: 'https://example.com',
      /** State string that is returned with the apple response */
      state: 'state',
      /** Nonce */
      nonce: 'nonce',
      /** Uses popup auth instead of redirection */
      usePopup: ${authOptions.usePopup},
    }} // REQUIRED
    /** General props */
    uiType="dark"
    /** className */
    className="apple-auth-btn"
    /** Removes default style tag */
    noDefaultStyle={false}
    /** Allows to change the button's children, eg: for changing the button text */
    buttonExtraChildren="Continue with Apple"
    /** Extra controlling props */
    /** Called upon signin success in case authOptions.usePopup = true -- which means auth is handled client side */
    onSuccess={(response) => console.log(response)} // default = undefined
    /** Called upon signin error */
    onError={(error) => console.error(error)} // default = undefined
    /** Skips loading the apple script if true */
    skipScript={false} // default = undefined
    /** Apple image props */
    iconProp={{ style: { marginTop: '10px' } }} // default = undefined
    /** render function - called with all props - can be used to fully customize the UI by rendering your own component  */
    render={(props) => <button {...props}>My Custom Button</button>}
  />
);

export default MyAppleSigninButton;
Note about the response's user object

onSuccess response object will contain the user object on the first time attempt only. Meaning if you make another signIn attempt for the same account you will not get the user object.

Raw JS functionality

a module called appleAuthHelpers is also exported to allow you to use the functionality without using the UI or relying on React. This works with any kind of frontend JS, eg: react, vue, etc... Note that you need to load the apple script yourself.

  • Importing the apple script:
    // using raw html:
    <script src="https://appleid.cdn-apple.com/appleauth/static/jsapi/appleid/1/en_US/appleid.auth.js" defer></script>
    
    // OR using react hooks:
    import { useScript, appleAuthHelpers } from 'react-apple-signin-auth';
    
    const myComponent = () => {
      useScript(appleAuthHelpers.APPLE_SCRIPT_SRC);
      // ...
    };
    
    export default myComponent;
  • Using appleAuthHelpers:
    import { appleAuthHelpers } from 'react-apple-signin-auth';
    // OR
    // import appleAuthHelpers from 'react-apple-signin-auth/dist/appleAuthHelpers'; // @unstable - might change with upgrades
    
    /**
     * perform apple signIn operation
     */
    appleAuthHelpers.signIn({
      authOptions: {
        // same as above
      },
      onSuccess: (response) => console.log(response),
      onError: (error) => console.error(error),
    });
    
    // OR
    
    /** promisified version - promise resolves with response on success or undefined on error -- note that this only work with usePopup: true */
    const response = await appleAuthHelpers.signIn({
      authOptions: {
        // same as above
      },
      onError: (error) => console.error(error),
    });
    
    if (response) {
      console.log(response);
    } else {
      console.error('Error performing apple signin.');
    }

Server-side authentication (nodeJS backend)

Another library exists for server/backend support for Apple signin apple-signin-auth

Usage

  • Install the library yarn add apple-signin-auth OR npm i apple-signin-auth
  • Implement JWT verification logic
    const appleSignin = require("apple-signin-auth");
    
    
    const { authorization, user } = req.body;
    
    try {
      const { sub: userAppleId } = await appleSignin.verifyIdToken(
        authorization.id_token, // We need to pass the token that we wish to decode.
        {
          audience: "com.example.web", // client id - The same one we used on the frontend, this is the secret key used for encoding and decoding the token.
          nonce: 'nonce' // nonce - The same one we used on the frontend - OPTIONAL
        }
      );
    } catch (err) {
      // Token is not verified
      console.error(err);
    }

Further resources:

Related Projects

Contributing

Pull requests are highly appreciated! For major changes, please open an issue first to discuss what you would like to change.

Getting Started

  • Clone the repo: git clone https://github.com/a-tokyo/react-apple-signin-auth
  • Install deps: yarn
  • Start webpack development server on localhost:3001: yarn start
  • To run/update the tests locally, run: yarn test -u

react-apple-signin-auth's People

Contributors

a-tokyo avatar christophermckay avatar erickinhou avatar thagana avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

react-apple-signin-auth's Issues

ReferenceError: regeneratorRuntime is not defined at node_modules/react-apple-signin-auth/dist/utils/waitForVar.js:21:46

when I tried to create a build on next.js application I got that error:

Build error occurred
ReferenceError: regeneratorRuntime is not defined
```
at node_modules/react-apple-signin-auth/dist/utils/waitForVar.js:21:46

at Object.<anonymous> /node_modules/react-apple-signin-auth/dist/utils/waitForVar.js:84:2)

at Module._compile (node:internal/modules/cjs/loader:1101:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
at Module.load (node:internal/modules/cjs/loader:981:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object. (node_modules/react-apple-signin-auth/dist/appleAuthHelpers/index.js:8:42)
at Module._compile (node:internal/modules/cjs/loader:1101:14) {
type: 'ReferenceError'

Uncaught TypeError: Cannot read property 'preventDefault' of undefined

Hey there!. Nice job doing this module!

image
image

I am trying to use this module with a custom button rendered but I am having problem with the event not being sent to handleClick.
image

I tried to solve, but even after digging I could not found what is wrong.
These two are two examples of detailed explanations around the problem:
https://www.jsdiaries.com/how-to-fix-cannot-read-property-preventdefault-of-undefined/
https://stackoverflow.com/questions/51004969/reactjs-cannot-read-property-preventdefault-of-undefined

I tried with simple buttons and everything works ok.
image

For the buttons i am using this module: https://www.npmjs.com/package/react-social-login-buttons
The strange thing is that I use the same button with react-google-login module and the button works just fine. So I´m in doubt if it is related to react-apple-signin-auth or react-social-login-buttons

What puzzles me is that i set onClick={renderProps.onClick} directly. So how could the module mess with anything?
Could anyone point me at some direction?
Thanks in advance.
Pucci

First time user object disclaimer

Hello

Thank you for this library it helped a lot. but when i was using it i had no idea that second time sign in will not return a user object.

would it be possible to have a small disclaimer to people who are new to apple signin auth and are using the library to know that bit of information?

Doesn't return user's data

After success authentication, Apple returns token and, optionally, user's data, such as name and email.
For some reason, this library ignores it and gives back only token and code.
I know that it works only for the first time, but even then there is nothing.

===
My bad, sorry, missed that user is next to authorization, not inside.

Custom callback onClick

It would be great to provide some callback when Apple button is clicked, in order to prevent app interaction when the popup is triggered.

New tag release

Hello

Thank you for the work you've done.
I am looking for typescript declaration which as introduced in #78,
version was updated in package.json, but no tag was created.
I can require commit or branch but would rather use tags.

Could you publish one?
Thanks in advance

onSuccess is not calling after successfull signin response

<div className="flex justify-center">
            <AppleSignin
              className="apple-auth-btn"
              authOptions={{
                clientId: 'com.example.www',
                scope: 'email name',
                redirectURI:
                  'https://www.example.com/auth/apple-authentication/callback',
                state: 'state',
                nonce: 'nonce',
                usePopup: true,
              }}
              buttonExtraChildren={'Sign in with Apple'}
              onSuccess={(response) => {
                console.log(response);
                alert('Okay');
              }}
              onError={handleAppleLoginFailure}
            />
          </div>

onSuccess not firing

Hi! onSuccess doesn't seem to be firing when the login completes and popup closes.

            authOptions={{
              clientId: "com.example.www",
              scope: 'email name',
              redirectURI: "https://example.com/en/signin",
              usePopup: true,
            }}
            uiType="dark"
            className="apple-auth-btn"
            noDefaultStyle={false}
            buttonExtraChildren="Continue with Apple"
            onSuccess={(response: any) => console.log(response)}
            onError={(error: any) => console.error(error)}
            skipScript={false}
            render={(props: any) => <Button
              {...props}
              variant="outline"
            >
              <FaApple className="mr-2 h-4 w-4" />
              Sign in with Apple
            </Button>}
          />```

No response using usePopup=true prop with appleAuthHelpers

Hi

I am trying your appleAuthHelpers.signIn function. below is my code. For some strange reason I don't get an onSuccess response.

I get the popup below

image

After clicking continue nothing happens

image

import React, { useCallback, useEffect, useRef, useState } from 'react';
import { appleAuthHelpers, useScript } from 'react-apple-signin-auth';
import {
  Alert,
  Button,
  ButtonGroup,
  ButtonGroupProps,
  Image
} from '@chakra-ui/react';
import { nanoid } from 'nanoid/non-secure';

const Social: React.FC<SocialProps> = ({ joinSession, ...rest }) => {
  const { t } = useTranslation();
  const dispatch = useDispatch();
  useScript(appleAuthHelpers.APPLE_SCRIPT_SRC);

const signInApple = useCallback(() => {
    const nonce = nanoid();
    appleAuthHelpers.signIn({
      authOptions: {
        clientId: config.apple.clientId,
        /** Requested scopes, seperated by spaces - eg: 'email name' */
        scope: 'email name',
        /** Apple's redirectURI - must be one of the URIs you added to the serviceID - the undocumented trick in apple docs is that you should call auth from a page that is listed as a redirectURI, localhost fails */
        redirectURI: config.apple.redirectUrl,
        state: 'state',
        /** Nonce */
        nonce,
        usePopup: true,
      },
      onSuccess: (response: AppleAuthResponse) => console.log(response),
      onError: (error: any) => console.error(error),
    });
  }, []);

return ( <Button
          w="100%"
          type="button"
          colorScheme="black"
          boxShadow="lg"
          leftIcon={
            <Image
              src={appleImage}
              alt="Apple"
              htmlWidth="1.22em"
              htmlHeight="auto"
              w="1.22em"
              h="auto"
              mr="2"
            />
          }
          onClick={signInApple}
        >
          {t('auth.ssoApple')}
        </Button>

)

};

export default Social;

Typescript support

Typescript declarations would make it a ton easier to use this package, at the moment the types aren't exposed correctly:

Could not find a declaration file for module 'react-apple-signin-auth'. '/home/user/docs/repo/react-web/node_modules/react-apple-signin-auth/dist/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/react-apple-signin-auth` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-apple-signin-auth';`

Uncaught in promise error when closing apple sign in

Hi

Im trying to catch the error 'popup_closed_by_user' when the you user closes the apple sign in. but the onError does not get called and I see there is an uncaught promise error. see image below

image

try {
      appleAuthHelpers.signIn({
        authOptions: {
          clientId: config.apple.clientId,
          /** Requested scopes, seperated by spaces - eg: 'email name' */
          scope: 'email name',
          /** Apple's redirectURI - must be one of the URIs you added to the serviceID - the undocumented trick in apple docs is that you should call auth from a page that is listed as a redirectURI, localhost fails */
          redirectURI: config.baseUrl,
          /** Nonce */
          nonce: nonce.current,
          usePopup: true,
        },
        onSuccess: onAppleSuccess,
        onError: (error: unknown) => console.info('error', error),
      });
    } catch (errorCaught) {
      console.info('errorCaught', errorCaught);
    }`

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.