GithubHelp home page GithubHelp logo

Comments (11)

israx avatar israx commented on June 3, 2024

hello @mpark1 . Apologies for any inconvenience using the library. Could you please share your amplify configuration ? Please refrain from adding any sensitive values.

Can you also manually configure Amplify and see if you are getting the same issue ?

from amplify-js.

cwomack avatar cwomack commented on June 3, 2024

@mpark1 to tag onto @israx's requests above, can you also share more of your frontend code that's part of your Auth flow as well as if there's any associated errors in the network tab or console?

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@israx @cwomack I’ll follow up with the amplify configuration and the Auth flow and the code in couple hours. In the meantime, I want to clarify how signinwithredirect should work.

Currently, I’m using Cognito for user sign up. My understanding was that when a user who hasn’t signed up on app should be able to click on ‘sign in with apple’ button which then should show the the apple sign in page -> user signs in and we get back the information about this apple account -> then that somehow signs up the user at the same time and automatically creates a user in my Cognito user pool. Is there some loophole in my understanding of how signinwithredirect works? I ask because I’m thinking maybe the user needs to sign up first through regular email and password option with Cognito, only then they should be able to sign in with idp.

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@israx Could you clarify what is meant by manually configuring Amplify? Do you mean using Amplify CLI?

Here's what I've attempted thus far:

  1. I followed everything step by step as illustrated in the official doc (https://docs.amplify.aws/gen1/react-native/build-a-backend/auth/add-social-provider/) except the section for Add custom state and Custom providers. Then when running my project with the code I shared, when I click on the apple sign-in on the front-end, the app simulator launches an in app browser but it does not take me to the apple sign-in page which I believe is because of the url missing my app's name in the beginning. I'll point out that the only difference I had from the official doc was that I used amplify update auth to add apple sign in.

  2. So I tried going into the AWS Cognito console and updated Sign In Experience by adding Federated sign in, just filling in all the items. I've double checked that I filled them with the correct team id, service id, key, etc obtained from Apple developers site. But nothing changed.

  3. I went into Amplify studio's Authentication section and repeated step 2.

  4. Then I tried with the Amplify CLI again, with amplify update auth, which strangely this time, asked me to provide team id, service id, key etc, although I've already filled in the same information from Cognito console.

I've run amplify push/pull every time I was updating the configuration with CLI.

Below is my cli-inputs.json

{ "version": "1", "cognitoConfig": { "identityPoolName": "milkywayXXXXXXXX_identitypool_XXXXXXXX", "allowUnauthenticatedIdentities": false, "resourceNameTruncated": "milkywXXXXXXXX", "userPoolName": "milkywayXXXXXXXX_userpool_XXXXXXXX", "autoVerifiedAttributes": [ "email" ], "mfaConfiguration": "OFF", "mfaTypes": [ "SMS Text Message" ], "smsAuthenticationMessage": "Your authentication code is {####}", "smsVerificationMessage": "Your verification code is {####}", "emailVerificationSubject": "Your verification code", "emailVerificationMessage": "Your verification code is {####}", "defaultPasswordPolicy": false, "passwordPolicyMinLength": 8, "passwordPolicyCharacters": [], "requiredAttributes": [ "email" ], "aliasAttributes": [], "userpoolClientGenerateSecret": false, "userpoolClientRefreshTokenValidity": 30, "userpoolClientWriteAttributes": [], "userpoolClientReadAttributes": [], "userpoolClientLambdaRole": "milkywXXXXXXXX_userpoolclient_lambda_role", "userpoolClientSetAttributes": false, "sharedId": "b2dd3f99", "resourceName": "milkywayXXXXXXXX", "authSelections": "identityPoolAndUserPool", "useDefault": "defaultSocial", "usernameAttributes": [ "email" ], "userPoolGroupList": [ "admin" ], "serviceName": "Cognito", "usernameCaseSensitive": false, "useEnabledMfas": true, "authRoleArn": { "Fn::GetAtt": [ "AuthRole", "Arn" ] }, "unauthRoleArn": { "Fn::GetAtt": [ "UnauthRole", "Arn" ] }, "breakCircularDependency": true, "dependsOn": [], "userPoolGroups": false, "adminQueries": false, "hostedUI": true, "hostedUIDomainName": "milkywayXXXXXXXX-XXXXXXXX", "authProvidersUserPool": [ "SignInWithApple" ], "hostedUIProviderMeta": "[{\"ProviderName\":\"SignInWithApple\",\"authorize_scopes\":\"email\",\"AttributeMapping\":{\"email\":\"email\"}}]", "oAuthMetadata": "{\"AllowedOAuthFlows\":[\"code\"],\"AllowedOAuthScopes\":[\"phone\",\"email\",\"openid\",\"profile\",\"aws.cognito.signin.user.admin\"],\"CallbackURLs\":[\"milkyway://\"],\"LogoutURLs\":[\"milkyway://\"]}", "authProviders": [] } }

When calling signInWithRedirect, the browser tries to open ap-northeast-2.amazoncognito.com which obviously doesn't exist on the server. I would have expected something like hostedUIDomainName.auth to be prepended but is missing in the url that should take me to the apple sign in page.

Attaching simulator screenshot for reference:

  • When sign in with apple button is pressed
    Simulator Screenshot - iPhone 13 - 2024-05-10 at 11 22 49
  • When clicking continue from the above screenshot
    Simulator Screenshot - iPhone 13 - 2024-05-10 at 11 23 28

Update: Strangely, when running on emulator, I see that the redirect url is https://milkyway
xxxxxxxx-XXXXXXXX-dev.auth.ap-northeast-2.amazoncognito.com/oauth2/authorize?redirect_uri=milkyway%3A%2F%2F&response_type=code&client_id=xxx&identity_provider=SignInWithApple&scope=phone%20email%20openid%20profile%20aws.cognito.signin.user.admin&state=xxx&code_challenge=xxx&code_challenge_method=S256 but even on the emulator the browser displays that the site can't be reached.

I was browsing through Amazon Cognito User pools App Integration where we can set up a domain, but regardless of setting the cognito domain or the custom domain there, I would be forced to use the hosted ui instead of my own sign in/sign up ui, right? I'm clueless at this point what could have gone wrong in the configuration.

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@cwomack I have a fairly simple Auth flow. I've included the SignIn page's code but bascially it's the first screen when my app launches when no user is signed in. And to summarize what SignIn screen contains, it just have the sign in with apple button which opens the webview when pressed and I would have expected it take me to the Apple's sign-in page. Right now, I am able to get the webview to open on my simulator but it never reaches the Apple's sign-in page and I don't get any console logs. The webview just displays a message that it doesn't exist on the server because the url it gets is "ap-northeast-2.amazoncognito.come" so no information about my app's domain is included. Also I don't get any console log when the webview opens, but when I close it, I get "res from Apple sign in: undefined".

It should be clear from this code that I'm implementing my own ui for signin/signup and we're not wrapping our app with hosted ui for authentication provided by amplify. For instance, I've seen examples that uses import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react-native'; and wraps the app with the Authenticator provider but we don't intend to use that. We also don't have any hub listeners set up anywhere in our project. Am I supposed to use Auth.federatedSignIn instead?

As far as I could gather from the official doc, using the Authenticator from @aws-amplify/ui-react-native shouldn't be necessary to implement social sign-in. Is this correct?

Index:

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';
import {Amplify} from 'aws-amplify';
import config from './src/amplifyconfiguration.json';
import 'react-native-gesture-handler';
import {initializePushNotifications} from 'aws-amplify/push-notifications';

Amplify.configure(config);
initializePushNotifications();

AppRegistry.registerComponent(appName, () => App);

App.tsx:

const App = () => {
  return (
    <Provider store={store}>
      <GestureHandlerRootView style={globalStyle.flex}>
        <BottomSheetModalProvider>
          <RootNavigation />
        </BottomSheetModalProvider>
      </GestureHandlerRootView>
    </Provider>
  );
};

SignIn code:

const SignIn = ({navigation}) => {
  const dispatch = useDispatch();
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const passwordRef = useRef(null);
  const [isLoggingIn, setIsLoggingIn] = useState(false);

  const onChangeEmail = useCallback(text => {
    setEmail(text.trim());
  }, []);
  const onChangePassword = useCallback(text => {
    setPassword(text.trim());
  }, []);

  const canGoNext = email && password;

  const onSubmit = useCallback(async () => {
    if (isLoggingIn) {
      return;
    }
    try {
      setIsLoggingIn(true);
      const {isSignedIn, nextStep} = await signIn({
        username: email,
        password: password,
      });
      if (isSignedIn) {
        const userId = await checkUser();
        dispatch(setCognitoUsername(userId));
        const response = await fetchUserFromDB(userId);
        dispatch(
          setOwnerDetails({
            name: response.name,
            email: response.email,
          }),
        );
      }

      // 미인증 계정 인증화면으로 보내기
      if (nextStep.signInStep === 'CONFIRM_SIGN_UP') {
        AlertBox('미인증 계정입니다', '', '인증하러가기', async () => {
          await resendSignUpCode({username: email});
          navigation.navigate('ConfirmAccount', {
            name: '',
            email: email,
            purpose: 'reconfirm',
            uri: '',
          });
        });
      }
    } catch (error) {
      console.log('error signing in: ', error);
      if (error.name === 'UserNotFoundException') {
        // [UserNotFoundException: User does not exist.]
        AlertBox(
          '존재하지 않는 계정입니다.',
          '회원가입을 진행해주세요.',
          '확인',
          () => {
            setEmail('');
            setPassword('');
          },
        );
      } else if (error.name === 'NotAuthorizedException') {
        // [NotAuthorizedException: Incorrect username or password.]
        AlertBox(
          '이메일 또는 비밀번호를 다시 확인해주세요.',
          '',
          '확인',
          'none',
        );
      }
    } finally {
      setIsLoggingIn(false);
    }
  }, [isLoggingIn, email, password]);

  const handleSignInWithApple = async () => {
    try {
      const resFromSignInWithApple = await signInWithRedirect({
        provider: 'Apple',
      });
      console.log('res from Apple sign in: ', resFromSignInWithApple);
    } catch (error) {
      console.log('Error signing in with Apple');
    }
  };

  const handleSignOut = async () => {
    try {
      await signOut();
    } catch (error) {
      console.log('error signing out: ', error);
    }
  };

  const renderEmailField = () => {
    return (
      <Input
        onChangeText={onChangeEmail}
        value={email}
        inputContainerStyle={[styles.inputContainerStyle, {marginBottom: -10}]}
        inputStyle={styles.inputStyle}
        label="이메일*"
        labelStyle={styles.labelStyle}
        placeholder="이메일을 입력해주세요"
        placeholderTextColor={'#d9d9d9'}
        onSubmitEditing={() => passwordRef.current?.focus()}
        returnKeyType={'next'}
        keyboardType={'email-address'}
      />
    );
  };

  const renderPasswordField = () => {
    return (
      <Input
        onChangeText={onChangePassword}
        value={password}
        ref={passwordRef}
        inputContainerStyle={[styles.inputContainerStyle, {marginBottom: -23}]}
        inputStyle={styles.inputStyle}
        label="비밀번호*"
        labelStyle={styles.labelStyle}
        placeholder="비밀번호를 입력해주세요"
        placeholderTextColor={'#d9d9d9'}
        keyboardType={Platform.OS === 'android' ? 'default' : 'ascii-capable'}
        secureTextEntry={true}
        maxLength={256}
      />
    );
  };

  const [checked, setChecked] = useState(true);
  const toggleCheckbox = () => setChecked(!checked);

  const renderAutoLogin = () => {
    return (
      <CheckBox
        title={'자동 로그인'}
        wrapperStyle={{marginLeft: -15}}
        textStyle={styles.checkBox.text}
        checked={checked}
        onPress={toggleCheckbox}
        iconType="material-community"
        checkedIcon={
          <Icon
            name="checkbox-outline"
            type="material-community"
            color="#6395E1"
            size={25}
            iconStyle={{marginRight: -3}}
          />
        }
        uncheckedIcon={
          <Icon
            name="checkbox-blank-outline"
            type="material-community"
            color="#939393"
            size={25}
            iconStyle={{marginRight: -3}}
          />
        }
      />
    );
  };

  const renderButtons = () => {
    return (
      <>
        <Button
          title={'로그인'}
          titleStyle={styles.loginButton.title}
          containerStyle={styles.loginButton.container}
          buttonStyle={globalStyle.backgroundBlue}
          disabled={!canGoNext}
          onPress={() => onSubmit()}
        />
        <Button
          title={'회원가입'}
          titleStyle={styles.signUpButton.title}
          type={'outline'}
          buttonStyle={styles.signUpButton.button}
          containerStyle={styles.signUpButton.container}
          onPress={() => navigation.navigate('SignUp')}
        />
      </>
    );
  };

  const renderFindPasswordButton = () => {
    return (
      <Pressable onPress={() => navigation.navigate('ForgotPassword')}>
        <Text style={styles.findPassWordText}>비밀번호 찾기</Text>
      </Pressable>
    );
  };

  const renderAppleSignInSignOutButtons = () => {
    return (
      <>
        <Pressable onPress={() => handleSignInWithApple()}>
          <Text style={styles.findPassWordText}>Sign in with Apple</Text>
        </Pressable>
        <Pressable onPress={() => handleSignOut()}>
          <Text style={styles.findPassWordText}>Sign out (Apple)</Text>
        </Pressable>
      </>
    );
  };

  return (
    <SafeAreaView style={[globalStyle.backgroundWhite, globalStyle.flex]}>
      <Text style={styles.appName}>은하수</Text>
      <View style={styles.spacer}>
        {renderEmailField()}
        {renderPasswordField()}
        {renderAutoLogin()}
        {renderButtons()}
        {renderFindPasswordButton()}
        {renderAppleSignInSignOutButtons()}
      </View>
    </SafeAreaView>
  );
};

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@israx Here's my latest amplifyconfiguration.json:

{
  "aws_project_region": "ap-northeast-2",
  "aws_mobile_analytics_app_id": "xxx",
  "aws_mobile_analytics_app_region": "ap-northeast-2",
  "Analytics": {
    "AWSPinpoint": {
      "appId": "xxxf",
      "region": "ap-northeast-2"
    }
  },
  "aws_appsync_graphqlEndpoint": "https://xxx.appsync-api.ap-northeast-2.amazonaws.com/graphql",
  "aws_appsync_region": "ap-northeast-2",
  "aws_appsync_authenticationType": "API_KEY",
  "aws_appsync_apiKey": "xxx",
  "aws_cognito_identity_pool_id": "ap-northeast-2:xxx",
  "aws_cognito_region": "ap-northeast-2",
  "aws_user_pools_id": "ap-northeast-2_SpQOUxXXq",
  "aws_user_pools_web_client_id": "xxx",
  "oauth": {
    "domain": "milkywayXXXXXXXX-XXXXXXXX-dev.auth.ap-northeast-2.amazoncognito.com",
    "scope": [
      "phone",
      "email",
      "openid",
      "profile",
      "aws.cognito.signin.user.admin"
    ],
    "redirectSignIn": "milkyway://",
    "redirectSignOut": "milkyway://",
    "responseType": "code"
  },
  "federationTarget": "COGNITO_USER_POOLS",
  "aws_cognito_username_attributes": [
    "EMAIL"
  ],
  "aws_cognito_social_providers": [
    "APPLE"
  ],
  "aws_cognito_signup_attributes": [
    "EMAIL"
  ],
  "aws_cognito_mfa_configuration": "OFF",
  "aws_cognito_mfa_types": [
    "SMS"
  ],
  "aws_cognito_password_protection_settings": {
    "passwordPolicyMinLength": 8,
    "passwordPolicyCharacters": []
  },
  "aws_cognito_verification_mechanisms": [
    "EMAIL"
  ],
  "aws_user_files_s3_bucket": "milkywaydeXXXXXX-dev",
  "aws_user_files_s3_bucket_region": "ap-northeast-2"
}

from amplify-js.

israx avatar israx commented on June 3, 2024

Hello @mpark1 . Thank you for all the context. To answer a couple of your questions.

using the Authenticator from @aws-amplify/ui-react-native shouldn't be necessary to implement social sign-in. Is this correct?

You don't have to use @aws-amplify/ui-react-native in order to implement social sign-in. As long as you are able to call the signInWithRedirect API is okay.

Could you clarify what is meant by manually configuring Amplify?

Yeah in addition to configure Amplify using the CLI. You can pass your configuration as follows

Amplify.configure(aws-exports) , or using a manual configuration

Amplify.configure({
  Auth: {
    Cognito: {
      userPoolId: "xxxxx",
      userPoolClientId: "xxxx",
      identityPoolId: "xxxxx",
      loginWith: {
        oauth: {
          domain: "your-domain",
          redirectSignIn: ["milkyway://"],
          redirectSignOut: ["milkyway://"],
          responseType: "code",
          scopes: [
            "email",
            "openid",
            "profile",
            "aws.cognito.signin.user.admin",
          ],}, }, }, }, }); })

from amplify-js.

israx avatar israx commented on June 3, 2024

Based on your dependencies I think you need to include the @aws-amplify/rtn-web-browser dep as well. You can refer to this section. Let us know if after installing this package your social sign-in ends up working

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@israx I do have @aws-amplify/rtn-web-browser in my project's root package.json which I didn't share here, but is there any other place that this dep should be included? I'm not sure if you meant this as the @aws-amplify/rtn-web-browser has to be included in the 'amplify' directory of my react native project.

from amplify-js.

israx avatar israx commented on June 3, 2024

The dep should be included in your root project, no in the amplify directory. Could you please share your package.json ?

from amplify-js.

mpark1 avatar mpark1 commented on June 3, 2024

@israx Sure! Here's my root project package.json

{
  "name": "MilkyWay",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "android": "react-native run-android",
    "ios": "react-native run-ios",
    "lint": "eslint .",
    "start": "react-native start",
    "test": "jest"
  },
  "dependencies": {
    "@amuizz/read-more-text": "^1.1.2",
    "@aws-amplify/cli": "^12.8.2",
    "@aws-amplify/react-native": "^1.0.28",
    "@aws-amplify/rtn-push-notification": "^1.2.28",
    "@aws-amplify/rtn-web-browser": "^1.0.29",
    "@bam.tech/react-native-image-resizer": "^3.0.7",
    "@craftzdog/react-native-buffer": "^6.0.5",
    "@gorhom/bottom-sheet": "^4.5.1",
    "@react-native-async-storage/async-storage": "^1.23.1",
    "@react-native-community/netinfo": "^11.1.1",
    "@react-native-masked-view/masked-view": "^0.3.1",
    "@react-native-seoul/kakao-login": "^5.4.1",
    "@react-navigation/bottom-tabs": "^6.5.11",
    "@react-navigation/core": "^6.4.10",
    "@react-navigation/material-top-tabs": "^6.6.5",
    "@react-navigation/native": "^6.1.9",
    "@react-navigation/native-stack": "^6.9.17",
    "@react-navigation/stack": "^6.3.20",
    "@reduxjs/toolkit": "^2.0.1",
    "@rneui/base": "^4.0.0-rc.7",
    "@rneui/themed": "^4.0.0-rc.8",
    "aws-amplify": "^6.2.0",
    "aws-sdk": "^2.1513.0",
    "react": "18.2.0",
    "react-native": "0.72.7",
    "react-native-date-picker": "^4.3.3",
    "react-native-device-info": "^10.12.0",
    "react-native-dropdown-picker": "^5.4.6",
    "react-native-fs": "^2.20.0",
    "react-native-gesture-handler": "^2.14.0",
    "react-native-get-random-values": "^1.11.0",
    "react-native-image-crop-picker": "^0.40.2",
    "react-native-image-picker": "^7.0.3",
    "react-native-keyboard-aware-scroll-view": "^0.9.5",
    "react-native-pager-view": "^6.2.3",
    "react-native-permissions": "^3.10.1",
    "react-native-quick-base64": "^2.0.8",
    "react-native-reanimated": "^3.6.1",
    "react-native-safe-area-context": "^4.7.4",
    "react-native-screens": "^3.27.0",
    "react-native-tab-view": "^3.5.2",
    "react-native-uuid": "^2.0.1",
    "react-native-vector-icons": "^10.0.2",
    "react-native-video": "^5.2.1",
    "react-navigation-header-buttons": "^11.1.1",
    "react-redux": "^9.0.2",
    "redux": "^5.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/runtime": "^7.20.0",
    "@react-native/eslint-config": "^0.72.2",
    "@react-native/metro-config": "^0.72.11",
    "@tsconfig/react-native": "^3.0.0",
    "@types/react": "^18.0.24",
    "@types/react-test-renderer": "^18.0.0",
    "babel-jest": "^29.2.1",
    "eslint": "^8.19.0",
    "jest": "^29.2.1",
    "metro-react-native-babel-preset": "0.76.8",
    "prettier": "^2.4.1",
    "react-test-renderer": "18.2.0",
    "typescript": "4.8.4"
  },
  "engines": {
    "node": ">=16"
  }
}

I double checked the federated sign in provider (apple) settings from the AWS Cognito console matched with what I have on my Apple Developer's page (like team ID, service ID, etc). I tried testing sign in with apple on my iPhone as well as the simulator and it turns out it was grabbing the "expected" redirect url from signinwithredirect, yet even when testing on the actual device, I'm still getting the "server cannot be found error" with the @aws-amplify/rtn-web-browser dep there. The behavior is the same on android.

Looking at the source code for signinwithredirect and comparing it to the url returned from the api call,

https://milkywayxxxxxxxx-xxxxxxxx-dev.auth.ap-northeast-2.amazoncognito.com/oauth2/authorize?redirect_uri=milkyway%3A%2F%2F&response_type=code&client_id=xxx&identity_provider=SignInWithApple&scope=phone%20email%20openid%20profile%20aws.cognito.signin.user.admin&state=xxx&code_challenge=xxx&code_challenge_method=S256

I assumed this is the correct url. (FYI, the client_id param matched with my amplify web client id). At this point, I'm clueless as to what could have gone wrong on my end when I was setting things up. I thought maybe the Apple private key uploaded to Cognito was incorrect/corrupted so I reuploaded that, but the key isn't even necessary during the step where the user should first be taken to the apple's sign in page when the url returned from signinwithredirect is provided. Please advise.

from amplify-js.

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.