Skip to content
This repository has been archived by the owner on Oct 12, 2018. It is now read-only.

Integration of basic authentication to User Pool #27

Open
mmailhos opened this issue Dec 10, 2016 · 11 comments
Open

Integration of basic authentication to User Pool #27

mmailhos opened this issue Dec 10, 2016 · 11 comments

Comments

@mmailhos
Copy link

Hello,

How can I do a basic authentication (e.g. get access token) to a user pool on Cognito ?

All I was able to see in the repo was connections to Identity Providers (such as Facebook...).

Thanks!

@mnichols
Copy link

mnichols commented Dec 15, 2016

It isn't supported in this. One user posted some code here that gave me a jump no connecting using user pools though.

It isn't clear what the roadmap is for proper AWS support of Cognito yet in react-native so for now the best hope imo is to cobble together bits from the ios and androis SDK's into react bridge code.

EDIT:
I misspoke I think...actually you can use the user pool as a cognito provider I think so the missing bit it authenticating against the pool using creds and fetching the idToken. The code linked above has example of that.
I am still trying to pull the pieces together myself but I think that is the right direction.

@mnichols
Copy link

Ok I was able to use AWSRNCognitoCredentials with the CognitoUserPool backing.
A few things I needed to do for understanding this non-documented thing:

JS bug

The AWSCognitoCredentials.js has a bug at line 48 which needs to be changed to:

      listener.addListener("LoginsRequestedEvent", async ({callbackId}) => {

You might get some odd JSON errors from RCTConvert if you don't make this change. Basically the event raised from the native code is LoginRequestEvent and that will send a payload of a NSDictionary that has something like { callbackId: <uuid> }.

Workflow

First, you need to authenticate against the user pool and pull the idToken out of the response. that is the missing thing in this sdk. The code I linked earlier can get a head start on that.

Once you have that, you need to use that token for using the federated identity flow.
When you call initWithOptions here you can call setLogins but only android needs that. What you need to be sure you provide is a getLogins callback func that returns a JS map (object) where the key is the following format:

var logins = {}
logins[`cognito-idp.${REGION}.amazonaws.com/${USER_POOL_ID}`] = idTokenFromUserPool;
  • If you try to use the accessToken you'll get a complain that it is missing the aud claim, which makes sense ... the access token trims out some claims from identity token.

Checking it out

On IOS I made these calls and they worked once I figured out all that other junk:

                const fetchedId = await AWSCognitoCredentials.getCredentialsAsync()
                console.log('called getCredentialsAsync', fetchedId)
                //this doesnt
                console.log('calling getIdentityIDAsync')
                const fetchedId2 = await AWSCognitoCredentials.getIdentityIDAsync()
                console.log('called getIdentityIDAsync', fetchedId2)

I confirmed that my getLogins callback was invoked as expected.
The getCredentialsAsync got a response like:

{
   "AccessKey": <hash>,
   "Expiration": <datetime>,
   "SecretKey": <hash>,
   "SessionKey": <hash>
}

And the getIdentityIDAsync got a response like:
{ identityId: "<region>:<uuid>" }

Deprecated usage of sendAppEventWithName

The SDK needs to be updated to subclass the RCTEventEmitter. See here for details on an approach for that.
It's unlikely this will be done here though so that looks like the next thing to solve...

HTH

@lielran
Copy link

lielran commented Jan 7, 2017

I find this use case very basic.
The first thing every developer will try to implement is basic authentication(login/logout/sign in...)

@mnichols
Copy link

mnichols commented Jan 7, 2017

@lielran the first drop of this SDK isnt concerned with the UserPool portion, but rather the Cognito Identity Provider side of the story which isnt concerned about login/logout.
I had to roll my own user pool stuff but once you have the id token you can use this sdk. Took me a while to recognize they are unrelated concerns (federation versus persona).

@mmailhos
Copy link
Author

mmailhos commented Jan 7, 2017

Hello,
I started to work back again on this recently. It seems that the easiest thing to do would be to get the id/access token using Native Bridge (I probably won't need the federation for now anyway).
As you said, @mnichols , this link is a great start.
I added the jars from the Android SDK and created the CognitoPackage implements ReactPackage class as well. I was finally able to compile the project.

Unfortunately, at the very end, I could not load the module, the third does not recognize './Cognito'.

import { NativeModules } from 'react-native';
module.exports = NativeModules.ToastAndroid;
import Cognito from './Cognito';

I will post as soon as I am able to get the token; In the meantime, if anyone was able to make the native bridge working, I'd be glad to hear how to did it :)

@mnichols
Copy link

mnichols commented Jan 7, 2017

@MathieuMailhos there is a missing bit in the Java stuff from that download. Follow the ReactNative docs for creating Native bridges for Android. Specifically make sure your MainActivity and MainApplication files have properly registered the module.
I've gotten pretty far along getting the android and ios sdks bound to ReactNative for user pool support but not quite ready. Their programming model isn't very friendly so reconsidering the approach.

@mmailhos
Copy link
Author

mmailhos commented Jan 7, 2017

Yes!

So I started to add the missing jars from the SDK:

$ ls android/app/libs/
aws-android-sdk-cognito-2.3.8.jar                 
aws-android-sdk-core-2.3.8.jar
aws-android-sdk-cognitoidentityprovider-2.3.8.jar

I updated MainApplication.java with:

import com.rctcognito.RCTCognitoPackage;
// and later in the List<ReactPackage>
new RCTCognitoPackage(),

I created the folder in src/main/java/com/rctcognito which includes:
AppHelper.java
Cognito.java (both from the AWS topic)
and RCTCognitoPackage.java, which is the Reat module:

package com.rctcognito;

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class RCTCognitoPackage implements ReactPackage {

        @Override
        public List<Class<? extends JavaScriptModule>> createJSModules() {
                return Collections.emptyList();
        }

        @Override
        public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
                return Collections.emptyList();
        }

        @Override
        public List<NativeModule> createNativeModules( ReactApplicationContext reactContext) {
                List<NativeModule> modules = new ArrayList<>();
                modules.add(new Cognito(reactContext));
                return modules;
        }
}

After all of that, I had a nicely compiling project (which means that package is well-loaded).
I Just had a problem to import it when doing:

import { NativeModules } from 'react-native';
module.exports = NativeModules.Cognito
import Cognito from './Cognito';

I have a big doubt about ./Cognito syntax

@mnichols
Copy link

mnichols commented Jan 7, 2017 via email

@lielran
Copy link

lielran commented Jan 10, 2017

@mnichols - I found it strange that the basic part is not supported(get a token) while the advanced is shown in the examples.

also, the solution above is valid for Android,right?

what about wrapping all aws apis via some v4 wrapper(e.g. https://github.com/leimd/react-native-aws-signature )

@mnichols
Copy link

mnichols commented Feb 12, 2017 via email

@nihp
Copy link

nihp commented Apr 19, 2018

@mnichols I am trying to get the token from the user pool. I don't know where i have lost. I can't able to create a user in the pool(Users and groups). Kindly provide any sample code to get the token. I am following this link https://medium.com/@thexap/user-authentication-with-react-native-and-amazon-cognito-982cca085916

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants