Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

React Native - Integrate User Pools with Federated Identities (FB login) #311

Closed
d-johan opened this issue Feb 19, 2018 · 32 comments
Closed
Labels
Auth Related to Auth components/category feature-request Request a new feature

Comments

@d-johan
Copy link

d-johan commented Feb 19, 2018

Do you want to request a feature or report a bug?

  • Bug

What is the current behavior?

  • Users created via cognito hosted UI in userPool are not linked to federated identity.

If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn't have dependencies other than AWS Amplify.
Steps followed for react native app:

  1. on 'singing in' open cognito hosted UI for FB authentication
  2. after FB signin, user is created in userPool and app receives access_token, id_token. User status in userPool is 'Enabled / EXTERNAL_PROVIDER'
  3. Use id_token returned in previous step to create an federatedIdentity by invoking Auth.federatedSignIn as follows:
 Auth.federatedSignIn('facebook', { token: params.id_token, expires_at }, user)
                    .then(crednetials => {
                      console.log("crednetials=",crednetials)
                    });
  1. Identity is created but in unauthenticated state.

What is the expected behavior?
I'dexpect the the identity to be Facebook enabled and linked to the userPool user rather than unauthenticated.

Which versions of Amplify, and which browser / OS are affected by this issue? Did this work in previous versions?

  • "aws-amplify": "^0.2.0", -
  • "expo": "^25.0.0",
  • "react": "16.2.0",
  • "react-native": "0.52.0"
@mlabieniec
Copy link
Contributor

mlabieniec commented Feb 20, 2018

@dodomasta thanks for the detailed issue. Cognito User Pools federation is not currently supported. Amplify federation currently runs through Cognito Identity and these two do no link together. We do have support for Cognito User Pools hosted UI on our roadmap which we'll use this issue as tracking that also supports the social federation as well when using the hosted UI.

Related to #45

@mlabieniec mlabieniec added the feature-request Request a new feature label Feb 20, 2018
@d-johan
Copy link
Author

d-johan commented Feb 20, 2018

Thanks for the update.

@diegoneg
Copy link

diegoneg commented Mar 3, 2018

Hi,

Looking at 'Auth.federatedSignIn', the problem appear related to async cache, chaining the calls is working on my test with FB login.

Hope this helps:

` * For federated login
* @param {String} provider - federation login provider
* @param {Object} response - response including access_token
* @param {String} user - user info
*/
AuthClass.prototype.federatedSignIn = function (provider, response, user) {

    if (Platform_1.default.isReactNative) {
        var that = this;
        let setCredPromise = new Promise(function (resolve, reject) {
            var token = response.token, expires_at = response.expires_at;
            that.setCredentialsFromFederation(provider, token, user);
            // store it into localstorage
            var that1 = that;
            Cache_1.default.setItem('federatedInfo', JSON.stringify({ provider: provider, token: token, user: user }), { priority: 1 }).then(function (federatedInfo) {
                dispatchAuthEvent('signIn', that1.user);
                logger.debug('federated sign in credentials', that1.credentials);
                resolve(that1.keepAlive());
            });
        });

        return Promise.resolve(setCredPromise);
    } else {
        var token = response.token, expires_at = response.expires_at;
        this.setCredentialsFromFederation(provider, token, user);
        // store it into localstorage
        Cache_1.default.setItem('federatedInfo', JSON.stringify({ provider: provider, token: token, user: user }), { priority: 1 });           
        dispatchAuthEvent('signIn', this.user);
        logger.debug('federated sign in credentials', this.credentials);
        return this.keepAlive();
    }
    
};`

Thx

@diegoneg
Copy link

diegoneg commented Mar 9, 2018 via email

@alexanderbh
Copy link

@diegoneg I can get aws credentials based on the facebook token with your fix. But nothing is stored in Auth for amplify. So if I call Auth.currentSession or similar nothing is there.

Do you experience that as well? Are you just signing in every time you need credentials?

@diegoneg
Copy link

@alexanderbh guess you're right and my fix can be partial, I just tested credentials were ok, i will have a deeper look and let you know if i can propose a fix about Auth currentSession

@mlabieniec mlabieniec added the Auth Related to Auth components/category label Mar 26, 2018
@MeixnerTobias
Copy link

@mlabieniec Is there a way to generate a user from Cognito user pool directly within the federatedSignIn?
We would like to send a cognito id_token to our API across from a federated sign in - is that currently possible?

As I understand current workaround is to recognise session of the user and then validate in the backend wheter token is issued from accounts.google.com or cognito endpoint?

Thank you.

@ganap
Copy link

ganap commented Apr 13, 2018

Any update on the ETA for federated login HOC for React Native?

@mlabieniec
Copy link
Contributor

@ganap we found some issues we need to work out within the core Auth class prior to completing the HOC for react native. Once we get past that we will complete / launch the hoc.

@ganap
Copy link

ganap commented Apr 13, 2018 via email

@mjmaix
Copy link
Contributor

mjmaix commented Apr 22, 2018

Hello everyone,

Any suggestions or workaround for this issue? I want to log in my react-native users using AWS Mobile Hub Cognito's federated identity (from active directory/SAML)?

@Simonaa27
Copy link

Hi,
I want to implement facebook and google login, with user pool identity providers, using mine UI (not the hosted one). I want to store the facebook/google attributes in the cognito user pool. Is there a way on how to do this? Any help would be appreciated.

@johnny-minty
Copy link

Hi, @mlabieniec, thanks for your work on this issue. Is there a beta build or branch the community can pull and integrate while you are working for a fix? Cheers Johnny

@lucaslc-sp
Copy link

@diegoneg Any news?

@diegoneg
Copy link

diegoneg commented May 7, 2018

apologize but didn't have time to complete it

@justinwaite
Copy link

So just to confirm:

It is currently impossible to use the federated logins feature for user pools on mobile. Is this correct? The docs clearly state that this is for mobile and web, yet web is the only one that can actually utilize it? Is there any hacky workaround without using identity pools?

This is such a headache 😕

@peter99330
Copy link

After reading this and a few other threads on GitHub and the AWS forums I am still confused about how to handle Sign In in a React Native app.

Originally I developed my backend using developer authenticated identities with Cognito Federated Identities. After switching to React Native and AWS Amplify I read the Documentation, which states that Federated Identities are not supported in React Native.
I then created a new Cognito UserPool and used the Amplify authenticator to Sign Up a new user. However, after the user signs up he is only created in the user pool. I cannot access any AWS resources. My Federated Identities are now filled with over 300 unauthenticated users, although there is only a single user in my User Pool.

How will I be able to use the Users from my User Pool to access AWS resources in React Native?

@dcgudeman
Copy link

Will this pull request fix this issue? #878

@mlabieniec
Copy link
Contributor

You can now use federatedSignIn on React Native via API and send in the token from any of the providers.

The PR you are referencing will provide actual react native components for google signin without needing to do yourself and pass the token.

@phoenecke
Copy link

I used federatedSignIn with a google token I got using https://github.com/react-native-community/react-native-google-signin. But, if I ever call Auth.currentUserCredentials() I will get the error: "refreshing federation token failed: no gapi auth2 available". The code in Amplify trying to refresh is expecting a window.gapi object.

My understanding is that, before each API call, the AWS temporary credentials may need to be refreshed, and that Amplify is trying to do that under the hood when I call currentUserCredentials(). Is there a way to set things up in react-native so that Amplify will properly refresh the AWS temp credentials and the google token when needed?

I may be missing something, or misunderstanding how the federated sign in flow is supposed to work.

@ttdatt
Copy link

ttdatt commented Jul 19, 2018

@mlabieniec I use federatedSignIn to login via FB on React Native but there is no user pool created, although a user was created in identity pool.

@nidsharm
Copy link

@ttdat89 , you might have two copies of aws-amplify in your node_modules, extra from aws-amplify-react-native. If so, delete the extra one. You could also clear your yarn/npm cache, remove the node_modules and clean install all dependencies to get rid of the error.
Please let us know if you still face the issue.

@ttdatt
Copy link

ttdatt commented Jul 20, 2018

@nidsharm I have only one aws-amplify, I also try clear & reset cache, remove node_modules but it didn't help, there is no user in userpool after login via FB
screen shot 2018-07-20 at 9 49 08 am

@ganap
Copy link

ganap commented Aug 1, 2018

@mlabieniec @nidsharm

What is the status on React Native HOC for Federated Login (FB / Google)

@dcoellarb
Copy link

@phoenecke did you find a workaround? i'm having the same issue on react native + aws amplify + react-native-google-signin

@phoenecke
Copy link

@dcoellarb I was just playing around with amplify and federated login, and I never really tried to build something real with it. I didn't do a lot of testing, but I think I ended up with something that seemed to work with google sign in and identity pool integration (I had no user pool involved). I think it is important to emphasize here, that federatedSignIn definitely will not do anything for anyone trying to integrate google login and user pools.

Here is the Auth component I ended up with, but like I said, I never used this for anything real.

import React from 'react'
import { StyleSheet, View, Text } from 'react-native'
import { Auth } from 'aws-amplify'
import { GoogleSignin, GoogleSigninButton } from 'react-native-google-signin'
import Home from './Home'

class AuthComponent extends React.Component {
  state = {
    user: null,
    loading: true,
  }

  componentDidMount = async () => {
    try {
      await GoogleSignin.configure({
        offlineAccess: false,
        iosClientId:
          'XXX.apps.googleusercontent.com',
        webClientId:
          'XXX.apps.googleusercontent.com',
      })

      const user = await GoogleSignin.currentUserAsync()
      await this.getCredentialsForGoogle(user)
    } catch (e) {
      console.log(e)
    } finally {
      this.setState({ loading: false })
    }
  }

  signin = async () => {
    try {
      this.setState({ loading: true })
      const user = await GoogleSignin.signIn()
      await this.getCredentialsForGoogle(user)
    } catch (e) {
      console.log(e)
    } finally {
      this.setState({ loading: false })
    }
  }

  signout = async () => {
    try {
      this.setState({ loading: true })
      await GoogleSignin.signOut()
      this.setState({ user: null })
    } catch (e) {
      console.log(e)
    } finally {
      this.setState({ loading: false })
    }
  }

  getCredentialsForGoogle = async googleUser => {
    if (googleUser) {
      const { idToken, accessTokenExpirationDate, email, name } = googleUser
      await Auth.federatedSignIn(
        'google',
        {
          token: idToken,
          expires_at: accessTokenExpirationDate,
        },
        {
          email,
          name,
        }
      )

      const currentUser = await Auth.currentAuthenticatedUser()

      this.setState({ user: currentUser })
    }
  }

  renderLogin() {
    return (
      <View style={styles.container}>
        <GoogleSigninButton
          style={{ width: 200, height: 48 }}
          size={GoogleSigninButton.Size.Wide}
          color={GoogleSigninButton.Color.Dark}
          onPress={this.signin}
        />
      </View>
    )
  }

  render() {
    if (this.state.loading) {
      return (
        <View style={styles.container}>
          <Text>Loading...</Text>
        </View>
      )
    }
    if (this.state.user && !this.state.loading) {
      return (
        <View style={styles.container}>
          <Home signout={this.signout} user={this.state.user} />
        </View>
      )
    }
    return this.renderLogin()
  }
}

AuthComponent.propTypes = {}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
})

export default AuthComponent

@dcoellarb
Copy link

tks @phoenecke it definitely point me in the right direction, i don't love having to call Auth.federatedSignIn on every app load, but hey it works ;), so is good workaround for now, just fyi i could not use GoogleSignin.currentUserAsync i had to use GoogleSignin.signInSilently, maybe i'm using a different version.

Tks again

@tobiastornros
Copy link

Repost:
So just to confirm:

It is currently impossible to use the federated logins feature for user pools on mobile. Is this correct? The docs clearly state that this is for mobile and web, yet web is the only one that can actually utilize it? Is there any hacky workaround without using identity pools?

This is such a headache 😕

@ganap
Copy link

ganap commented Aug 23, 2018

Are you guys ever going to fix this for React Native? The documentation says it works for both React and React Native. But this pull request #878 is stuck in review for the last 3 months.

@RongoDog
Copy link

I got this working on native for google by getting federatedInfo from the cache. This gives me access to the JWT token, but facebook login does not seem to store this. Big headache..

@ASteinheiser
Copy link

Yeah, I got Facebook logins working on React Native, but my only issue now is that the token seems to be expiring and give me an "Access Denied" on all my requests, until I re-auth with FB. It would be nice if it was handled the same way as the web sdk worked, where it automatically refreshed your tokens. Such a headache...

@github-actions
Copy link

This issue has been automatically locked since there hasn't been any recent activity after it was closed. Please open a new issue for related bugs.

Looking for a help forum? We recommend joining the Amplify Community Discord server *-help channels or Discussions for those types of questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jun 13, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Auth Related to Auth components/category feature-request Request a new feature
Projects
None yet
Development

No branches or pull requests