## OAuth and Federation Overview [OAuth 2.0](https://en.wikipedia.org/wiki/OAuth) is the common Authorization framework used by web and mobile applications for getting access to user information ("scopes") in a limited manner. Common analogies you will hear in OAuth is that of boarding a plane or staying in a hotel - showing your identification is the Authentication piece (signing into an app) and using the boarding pass/hotel key is what you are Authorized to access. OAuth support in Amplify uses Cognito User Pools and supports federation with social providers, which will automatically create a corresponding user in the User Pool after a login. [OIDC](https://en.wikipedia.org/wiki/OpenID_Connect) tokens are available in the app after the application has completed this process. import all0 from "/src/fragments/lib/auth/common/social_signin_web_ui/setup_auth_provider.mdx"; ## Configure Auth Category Once you have the social provider configured, run the following in your project’s root folder: ```bash amplify add auth ## "amplify update auth" if already configured ``` Choose the following options (the last steps are specific to Facebook here but are similar for other providers): ```console ? Do you want to use the default authentication and security configuration? `Default configuration with Social Provider (Federation)` ? How do you want users to be able to sign in? `Username` ? Do you want to configure advanced settings? `No, I am done.` ? What domain name prefix you want us to create for you? `(default)` ? Enter your redirect signin URI: `http://localhost:3000/` ? Do you want to add another redirect signin URI `No` ? Enter your redirect signout URI: `http://localhost:3000/` ? Do you want to add another redirect signout URI `No` ? Select the social providers you want to configure for your user pool: `` ``` You can configure you application to use more than one redirect URL. For more information, refer to the [Redirect URLs](#redirect-urls) section. import all1 from "/src/fragments/lib/auth/common/social_signin_web_ui/configure_auth_category.mdx"; ## Setup frontend After configuring the OAuth endpoints (Cognito Hosted UI), you can integrate your App by invoking `Auth.federatedSignIn()` function. Passing `LoginWithAmazon`, `Facebook`, `Google`, or `SignInWithApple` on the `provider` argument (e.g `Auth.federatedSignIn({ provider: 'LoginWithAmazon' })`) will bypass the Hosted UI and federate immediately with the social provider as shown in the below React example. If you are looking to add a custom state, you are able to do so by passing a string (e.g. `Auth.federatedSignIn({ customState: 'xyz' })`) value and listening for the custom state via Hub. ```ts import React, { useEffect, useState } from 'react'; import { Amplify, Auth, Hub } from 'aws-amplify'; import { CognitoHostedUIIdentityProvider } from '@aws-amplify/auth'; import awsConfig from './aws-exports'; Amplify.configure(awsConfig); function App() { const [user, setUser] = useState(null); const [customState, setCustomState] = useState(null); useEffect(() => { const unsubscribe = Hub.listen("auth", ({ payload: { event, data }}) => { switch (event) { case "signIn": setUser(data); break; case "signOut": setUser(null); break; case "customOAuthState": setCustomState(data); } }); getUser(); return unsubscribe; }, []); const getUser = async (): Promise => { try { const currentUser = await Auth.currentAuthenticatedUser(); setUser(currentUser); } catch(error) { console.error(error); console.log("Not signed in"); } }; return (
{user?.getUsername()}
); } ```
```javascript import React, { useEffect, useState } from 'react'; import { Amplify, Auth, Hub } from 'aws-amplify'; import { CognitoHostedUIIdentityProvider } from '@aws-amplify/auth'; import awsConfig from './aws-exports'; Amplify.configure(awsConfig); function App() { const [user, setUser] = useState(null); const [customState, setCustomState] = useState(null); useEffect(() => { const unsubscribe = Hub.listen("auth", ({ payload: { event, data } }) => { switch (event) { case "signIn": setUser(data); break; case "signOut": setUser(null); break; case "customOAuthState": setCustomState(data); } }); Auth.currentAuthenticatedUser() .then(currentUser => setUser(currentUser)) .catch(() => console.log("Not signed in")); return unsubscribe; }, []); return (
{user && user.getUsername()}
); } ```
You can also use the [Authenticator UI component](https://ui.docs.amplify.aws/react/components/authenticator) to add social sign in flow to your application. Visit [Social Provider](https://ui.docs.amplify.aws/react/components/authenticator/configuration#social-providers) section to learn more. ### Deploying to Amplify Console To deploy your app to Amplify Console with continuous deployment of the frontend and backend, please follow [these instructions](https://docs.aws.amazon.com/amplify/latest/userguide/environment-variables.html#creating-a-new-backend-environment-with-authentication-parameters). ### Redirect URLs For *Sign in Redirect URI(s)* inputs, you can put one URI for local development and one for production. Example: `http://localhost:3000/` in dev and `https://www.example.com/` in production. The same is true for *Sign out redirect URI(s)*. **Note:** if you have multiple redirect URI inputs, you'll need to handle both of them where you configure your Amplify project. For example: ```javascript import awsConfig from './aws-exports'; const isLocalhost = Boolean( window.location.hostname === "localhost" || // [::1] is the IPv6 localhost address. window.location.hostname === "[::1]" || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ ) ); // Assuming you have two redirect URIs, and the first is for localhost and second is for production const [ localRedirectSignIn, productionRedirectSignIn, ] = awsConfig.oauth.redirectSignIn.split(","); const [ localRedirectSignOut, productionRedirectSignOut, ] = awsConfig.oauth.redirectSignOut.split(","); const updatedAwsConfig = { ...awsConfig, oauth: { ...awsConfig.oauth, redirectSignIn: isLocalhost ? localRedirectSignIn : productionRedirectSignIn, redirectSignOut: isLocalhost ? localRedirectSignOut : productionRedirectSignOut, } } Amplify.configure(updatedAwsConfig); ``` ### Full Sample ```ts import { useEffect, useState } from 'react'; import { Amplify, Auth, Hub } from 'aws-amplify'; import awsConfig from './aws-exports'; const isLocalhost = Boolean( window.location.hostname === 'localhost' || // [::1] is the IPv6 localhost address. window.location.hostname === '[::1]' || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ ) ); // Assuming you have two redirect URIs, and the first is for localhost and second is for production const [ localRedirectSignIn, productionRedirectSignIn, ] = awsConfig.oauth.redirectSignIn.split(','); const [ localRedirectSignOut, productionRedirectSignOut, ] = awsConfig.oauth.redirectSignOut.split(','); const updatedAwsConfig = { ...awsConfig, oauth: { ...awsConfig.oauth, redirectSignIn: isLocalhost ? localRedirectSignIn : productionRedirectSignIn, redirectSignOut: isLocalhost ? localRedirectSignOut : productionRedirectSignOut, } } Amplify.configure(updatedAwsConfig); function App() { const [user, setUser] = useState(null); useEffect(() => { Hub.listen('auth', ({ payload: { event, data }}) => { switch (event) { case 'signIn': case 'cognitoHostedUI': getUser(); break; case 'signOut': setUser(null); break; case 'signIn_failure': case 'cognitoHostedUI_failure': console.log('Sign in failure', data); break; } }); getUser(); }, []); const getUser = async (): Promise => { try { const userData = await Auth.currentAuthenticatedUser(); setUser(userData) } catch(error) { console.error(error); console.log("Not signed in"); } }; return (

User: {user ? JSON.stringify(user.attributes) : 'None'}

{user ? ( ) : ( )}
); } export default App; ```
```js import { useEffect, useState } from 'react'; import { Amplify, Auth, Hub } from 'aws-amplify'; import awsConfig from './aws-exports'; const isLocalhost = Boolean( window.location.hostname === 'localhost' || // [::1] is the IPv6 localhost address. window.location.hostname === '[::1]' || // 127.0.0.1/8 is considered localhost for IPv4. window.location.hostname.match( /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ ) ); // Assuming you have two redirect URIs, and the first is for localhost and second is for production const [ localRedirectSignIn, productionRedirectSignIn, ] = awsConfig.oauth.redirectSignIn.split(','); const [ localRedirectSignOut, productionRedirectSignOut, ] = awsConfig.oauth.redirectSignOut.split(','); const updatedAwsConfig = { ...awsConfig, oauth: { ...awsConfig.oauth, redirectSignIn: isLocalhost ? localRedirectSignIn : productionRedirectSignIn, redirectSignOut: isLocalhost ? localRedirectSignOut : productionRedirectSignOut, } } Amplify.configure(updatedAwsConfig); function App() { const [user, setUser] = useState(null); useEffect(() => { Hub.listen('auth', ({ payload: { event, data } }) => { switch (event) { case 'signIn': case 'cognitoHostedUI': getUser().then(userData => setUser(userData)); break; case 'signOut': setUser(null); break; case 'signIn_failure': case 'cognitoHostedUI_failure': console.log('Sign in failure', data); break; } }); getUser().then(userData => setUser(userData)); }, []); function getUser() { return Auth.currentAuthenticatedUser() .then(userData => userData) .catch(() => console.log('Not signed in')); } return (

User: {user ? JSON.stringify(user.attributes) : 'None'}

{user ? ( ) : ( )}
); } export default App; ```
### Catching Errors In order to catch errors when using `Auth.federatedSignIn()` you can use the [Hub](/lib/utilities/hub/q/platform/js/) eventing system provided by Amplify to listen for the `signIn_failure` event. ```ts import { Hub } from 'aws-amplify' Hub.listen('auth', (data) => { if (data.payload.event === 'signIn_failure') { // Do something here } }) ``` ```js import { Hub } from 'aws-amplify' Hub.listen('auth', (data) => { if (data.payload.event === 'signIn_failure') { // Do something here } }) ```