# Implement Social Sign In

Source: https://dev.arcxp.com/subscriptions/identity/build/how-to-implement-social-sign-in/

Implementing social sign-in options allows users to create accounts without needing to remember additional passwords. This can improve user experience and reduce friction. This approach not only simplifies the login process for users but also offloads the responsibility of managing passwords and related security concerns to specialized services.

Arc XP Subscription supports direct integration with different Third-party Authentication providers: Google, Facebook and Apple.

In this document, we will walk through the process of implementing each one of the Third-party social providers we support.

> **Note:**
> 
> We will walk through this implementation using our SDK methods, but if you need to call the APIs directly, please check [How-to Connect and log in with Arc XP Identity SDKs and APIs on the web](https://dev.arcxp.com/subscriptions/identity/build/connect-and-login-with-arc-xp-identity-sdks-and-apis/) to see the API that our SDK method is wrapping.
> 
> Make sure the third-party authentication providers are set up properly. Check [Configure: Third-party Authentication providers, Google, Facebook and Apple](https://dev.arcxp.com/subscriptions/identity/configure/third-party-authentication-providers-facebook-google-apple/) for more details. Also you need to have the Identity SDK initialized.

To initialize the Facebook and Google buttons and initialize the Apple connection, you will need to use the settings configured in the Admin tool. When you land on the page, it’s necessary to retrieve the site configurations.

```js
import Identity from '@arc-publishing/sdk-identity';
...
const [siteConfigs, setSiteConfigs] = useState();
useEffect(()=>{
  const getSiteConfigs = async () => {
      try {
        await Identity.getConfig().then(config => {
          setSiteConfigs(config);
        });
      } catch (e) {
        alert(e.message);
      }
    };
    getSiteConfigs();
},[]);
```

`Identity.getConfig()` will return **facebookAppId**, **googleClientId**, **teamId**, **keyId**, among other values, which are used for implementing Google, Facebook and/or Apple. **facebookAppId** and **googleClientId** could be an string with several valued delimited by “commas” (i.e. multiple appIds and clientIds), make sure you are grabbing the right value to initialize the buttons.

## Implementing Sign In with Facebook

1. Load the Facebook JavaScript SDK library and initializes the Facebook SDK.  
```js
import Identity from '@arc-publishing/sdk-identity';
...
useEffect(() => {
    if(facebookAppId){
        Identity.initFacebookLogin(siteConfigs?.facebookAppId);
    }
}, [appId]);
```
`Identity.initFacebookLogin(appId)` is on charge to load the Facebook JavaScript SDK, which is a library provided by Facebook that allows developers to integrate Facebook’s features. Once the library is loaded, this method also calls `FB.init()` (Check [Quickstart: Facebook SDK for JavaScript](https://developers.facebook.com/docs/javascript/quickstart/) for more details).
2. Add the Facebook button.  
```js
<div
    className="fb-login-button"
    data-width="320"
    data-size="large"
    data-button-type="login_with"
    data-scope="public_profile,email"
    data-auto-logout-link="false"
    data-use-continue-as="true"
    data-onlogin="window.onFacebookSignOn()"
/>
```
3. Making `Identity.facebookSignOn()` globally accessible in the browser’s JavaScript context by wrapping this into the `onFacebookSignOn` async function.  
```js
if (!window.onFacebookSignOn) {
    window.onFacebookSignOn = async () => {
        try {
            await Identity.facebookSignOn();
        } catch (e) {
            alert(e.message);
        }
    };
}
```
`Identity.facebookSignOn()` is intended to be used as a callback (passed as data-onlogin or onlogin) to the “Facebook Login” button provided by Facebook. It checks if the user’s login status is “connected“. If the status is true , `Identity.facebookSignOn()` calls `Identity.socialLogin('facebook', {credential})`, passing the credentials/token provided by Facebook. If the response is successful, the user is logged into the Arc XP Identity.

### Using a custom Facebook button

Sometimes, due to the style requirements of your site, you may need to create a custom button, which cannot be achieved using the default login button provided by Facebook. In these cases, you will need to make a few changes to your implementation. Please check [Facebook Login Best Practices](https://developers.facebook.com/docs/facebook-login/best-practices) to ensure you meet Facebook’s requirements.

1. Load the Facebook JavaScript SDK library and initializes the SDK.  
```js
useEffect(() => {
    if(facebookAppId){
        Identity.initFacebookLogin(appId, null, true);
    }
}, [appId]);
```
2. Add the Facebook button.  
```js
<Button
    id="facebook-btn"
    variant="secondary-reverse"
    iconLeft={FacebookIcon}
    className={`${className}__Facebook`}
    onClick={() => window.onFacebookSignOn()}
>
    Sign In with Facebook
</Button>
```

## Implementing Sign In with Google

If you are on a React-based app, we recommend you use our [@arcxp/react-sign-in-with-google](https://github.com/arcxp/arc-commerce-sdks/pkgs/npm/react-sign-in-with-google) React components (you need access to the repository). This is the recommended approach for Pagebuilder sites as well.

Non-React-based sites can use the `Identity.signInWithGoogle` SDK but require more developer effort to integrate.

### React Sign In with Google

You must first have read access to the [@arcxp/react-sign-in-with-google](https://github.com/WPMedia/arc-commerce-sdks/tree/main/packages/react-siwg) Github Package repository. If your Github account does not have read access to the Github Packages under the @arcxp Github org, please reach out to [Arc XP Customer Support](https://support.arcpublishing.com/). Add your Github developer token to your .npmrc file, then install the package to your React project.

```js
npm install @arcxp/react-sign-in-with-google
yarn add @arcxp/react-sign-in-with-google
```

`@arcxp/react-sign-in-with-google` makes use of the context/provider pattern to scope your Identity & Sign In With Google configuration to a tree of components in your React application.

1. Load the Sign In With Google client library and initialize the SDK  
The `ArcSiwgContextProvider` performs the setup and initialization steps outlined in the Sign In With Google documentation.  
When it is mounted in your application, it will:

  - Load the Sign In With Google client library
  - Call `google.accounts.id.initialize()`
  - Optionally render the Google One Tap experience  
```js
import React from 'react';
import { createRoot } from 'react-dom';
import ArcSiwgContextProvider from '@arcxp/react-sign-in-with-google/lib-esm/ArcSiwgContext';
import Identity from '@arc-publishing/sdk-identity';
export const App = ({children}) => {
    return (
        <ArcSiwgContextProvider
            arcIdentity={Identity}
            displayOneTap
            onLoginSuccess={() => {
                // remove regwall or redirect to profile page
            }}
            onLoginFailure={e => {
                console.error(e);
            }}
            googleIdConfiguration={{
                auto_select: true
            }}
        >
        {/* Your app here */}
        </ArcSiwgContextProvider>
    );
};
const container = document.getElementById('app');
const root = createRoot(container);
root.render(
    <App/>
);
```
`onLoginSuccess`: function. The “default” onLoginSuccess that is called after the user successfully signs in with Google & receives valid credentials from Arc Identity. Provide a function to perform post login actions such as:

  - removing any registration walls
  - updating UI state to indicate the user is logged in
  - redirecting to the home/profile/etc. page as appropriate  
`onLoginFailure`: function. The “default” onLoginFailure that is called after the user fails to log in successfully with Google. Provide a function to perform post login failure actions such as displaying errors.  
`googleIdConfiguration`: object. takes all the fields described in [Sign In With Google JavaScript API reference | Authentication | Google for Developers](https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration)  
`displayOneTap`: boolean. if this parameter is set to true, AND the user is logged out from Arc Identity’s perspective, the Google One Tap prompt will render to the user.
2. Include the Sign In with Google button as part of the page.  
`ArcSiwgButton` renders the Sign In With Google button & can be used for user login and registration. This component MUST be rendered as a descendent of `ArcSiwgContextProvider` in your component tree. `ArcSiwgButton` accepts optional “onLoginSuccess” and “onLoginFailure” props that, if defined, are used instead of the default “onLoginSuccess” and “onLoginFailure” functions provided to ArcSiwgContextProvider as props.  
```js
import React from 'react';
import ArcSiwgButton from '@wpmedia/react-sign-in-with-google/lib-esm/ArcSiwgButton';
export const Login = () => {
    return (
        <>
        <h1>Login</h1>
        <>{/* login form here */}
        <ArcSiwgButton
            gsiButtonConfiguration={{
                type: 'standard',
                theme: 'outline',
                size: 'large',
                text: 'signin_with',
                shape: 'rectangular',
                logo_alignment: 'left',
                width: '400'
            }}
            onLoginSuccess={() => {
                // overrides the default "onLoginSuccess" passed to the closest ancestor ArcSiwgContextProvider
                history.push('/profile');
            }}
            onLoginFailure={(e) => {
                console.error('error logging in', e);
            }}
        />
        </>
    );
};
```

### Javascript implementation

If you are not using a React or Pagebuilder based site, Arc XP Identity supports implementing Sign In With Google using the JavaScript Arc XP Identity SDK directly.

The `Identity.signInWithGoogle()` method accepts the Google OAuth credential response, internally it calls `socialLogin('google', {credentials})` passing the credentials/token to the Arc XP Identity API to exchange for Arc XP Identity access and refresh tokens. Use `Identity.signInWithGoogle` to pass as callbacks to the [Sign In With Google SDK](https://developers.google.com/identity/gsi/web/guides/client-library).

1. Load the [Sign In With Google client library](https://developers.google.com/identity/gsi/web/guides/client-library) in your `index.html`.  
```js
<html>
    <head>
    <script src="https://accounts.google.com/gsi/client" async></script>
    </head>
    <body>
    </body>
</html>
```
2. Initialize the Sign In With Google library and Identity SDK  
When the Google client library loads on the page, initialize the Arc XP Identity SDK and Google client library.  
Remember that Arc XP Identity supports login through only the popup mode when specifying optional Google ID Configuration values. For more information, see the following sections in Google Identity’s documentation:

  - [Method: google.accounts.id.initialize](https://developers.google.com/identity/gsi/web/reference/js-reference#google.accounts.id.initialize)
  - [Data type: IdConfiguration](https://developers.google.com/identity/gsi/web/reference/js-reference#IdConfiguration)  
index.js  
```js
import Identity from '@arc-publishing/sdk-identity';
window.onload(() => {
    if (!google?.accounts) {
        throw new Error('Google client library is not loaded.');
    }
    const googleIdConfig = {
        client_id: siteConfigs?.googleClientId,
        callback: (credentialResponse) => {
            return Identity.signInWithGoogle(credentialResponse)
            .then(() => {
                // handle successful login
            }).catch(e => {
                console.error('error logging in', e);
                // handle login failure
                // i.e. display error message,
            });
        },
        auto_select: true
    };
    google.accounts.id.initialize(googleIdConfig);
});
```
3. Render the Sign In With Google button  
When the Arc XP Identity SDK and Google client library are both loaded and initialized, you can render the Sign In With Google button. In your login page, include a `div` with a unique ID for your Sign In With Google button. We use this ID to tell the Google client library where to render the Sign In With Google button.  
```js
<div
    id='sign-in-with-google-button'
/div>
```
Then, in your `index.js`, add the following code after where you call `google.accounts.id.initialize()`.  
```js
google.accounts.id.renderButton(
    document.getElementById('sign-in-with-google-button'),
    { theme: 'outline', size: 'large' }
);
```
You can pass different attributes to customize the Google Login button. Please refer to the [Data type: GsiButtonConfiguration](https://developers.google.com/identity/gsi/web/reference/js-reference) section for more details.
4. Open the One Tap prompt  
To open the One Tap prompt, call `google.accounts.id.prompt` after the Google client library loads and initializes.  
Before you call this function, you should make sure the user is not already logged in to Arc XP by using `Identity.isLoggedIn`. See [Method: google.accounts.id.prompt](https://developers.google.com/identity/gsi/web/reference/js-reference#google.accounts.id.prompt) in Google’s documentation.

### Using a custom Google button

Due to the style requirements of your site, you may need to create a custom Google Login button. If you are using a custom button, you will need to make some changes to the code provided above. Before doing that, make sure you are following the [Sign In with Google branding guidelines](https://developers.google.com/identity/branding-guidelines). The code provided in the **Step 3** (previous section) should be updated with the custom button. It is on charge to call the google prompt for the One Tap user experience. Check [Sign In With Google JavaScript API reference](https://developers.google.com/identity/gsi/web/reference/js-reference) and [Understand the One Tap user experience](https://developers.google.com/identity/gsi/web/guides/features#exponential%5Fcooldown) for more details.

```js
<Button
  id="custom-google-signin-btn"
  iconLeft={GoogleIcon}
  className={`${className}__Google`}
  onClick={() =>
  window?.google?.accounts?.id?.prompt((notification) => {
    if (notification.isSkippedMoment()) {
          alert(googleNotification);
      // Remove cookie works in Safari
      document.cookie = `g_state=;path=/;expires=Thu, 01 Jan 1970 00:00:01 GMT`;
    window.google.accounts.id.prompt();
    }
  })
  }
>
  Sign In with Google
</Button>
```

## Implementing Sign In with Apple

1. Include the Apple button as part of the page.  
```js
<button type="button" onClick={() => Identity.initAppleSignOn()}>
    Sign In with Apple
</button>
```
">  
`Identity.initAppleSignOn()` redirects the user to the Apple page. After the user completes their authentication, he/she is redirected back to the URL (i.e., redirect URL) defined in the Admin tool as part of the authentication provider settings for Apple.
2. Authenticate the user on Arc XP Identity.  
The redirect URL has additional query params, code param is the one you will need in order to complete the authentication on the Arc XP Identity side.  
```js
import React, { useEffect } from 'react';
import qs from 'querystring';
import Identity from '@arc-publishing/sdk-identity';
export const AppleRedirect = ({ location: { search }, history }) => {
    const { code } = qs.parse(search.slice(1));
    useEffect(() => {
        const redirect = () => {
            Identity.appleSignOn(code).then(() => {
            history.push('/profile');
            });
        };
        redirect();
    }, [code]);
    return <h3>Redirecting...</h3>;
};
```
`Identity.appleSignOn()` internally calls `socialLogin('apple', { credentials: code})`. If the authentication on the Arc XP Identity is successful, the user is logged In into the system.

> **Note:**
> 
> Any user who wants to Sign in with Apple will need an Apple ID. In addition, two-factor authentication should be set up (see [Two-Factor Authentication For Apple ID](https://support.apple.com/en-au/HT204915)).
> 
> Sign in with Apple makes it easy for users to sign in to your apps and websites using their Apple ID. All accounts are protected with two-factor authentication for superior security, and Apple will not track users’ activity in your app or website.
> 
> **Note:** Apple users can opt out of sharing their email address when signing in with an Apple ID. If the user chooses to hide their email address, Apple creates a Unique, Random Email Address Is Created, So (Their) Personal Email Address Isn’t Shared With The App Or Website Developer During The Account Setup And Sign In Process. [This Address Is Unique To (The User) And The Developer And Follows This Format:](https://support.apple.com/en-us/HT210425) `<Unique-Alphanumeric-String>@Privaterelay.Appleid.Com`. If the customer contacts support, the agent can look up their account using the relay address created by Apple or other information the customer provided as part of the customer’s Identity account after signing in with Apple.
