amazon-archives / amazon-cognito-identity-js

Amazon Cognito Identity SDK for JavaScript
Other
986 stars 452 forks source link

Cross domain user session #598

Open codal-ksharma opened 6 years ago

codal-ksharma commented 6 years ago

I have my app at http://example.com where I am doing the authentication(authenticateUser) and after that I am redirecting to http://app.example.com. When I try to get the session using var cognitoUser = userPool.getCurrentUser();, I am getting null.

Is it event possible to have user session in cross domain.

I tried Use case 26. Using cookies to store cognito tokens from https://github.com/aws/amazon-cognito-identity-js, but that is giving TypeError AWSCognito.CognitoIdentityServiceProvider.CookieStorage is not a constructor

var poolData = { UserPoolId: 'aaaaaaaaaa', ClientId: 'bbbbbbbbbbbbbbbbb', Storage: new AWSCognito.CognitoIdentityServiceProvider.CookieStorage({domain: ".example.com"}) };

marlontrapp commented 6 years ago

I've tried to reproduce your error, but I wasn't able to do, with angular. Could you give me more details about your environment? Did you follow the Usage topic?

itrestian commented 6 years ago

Just following up, what is the environment you are using?

woodpav commented 6 years ago

import { CookieStorage } from 'amazon-cognito-identity-js'; new CookieStorage({ ... })

maxmartynov commented 6 years ago

Wrapping to setTimeout may help. Looks like it requires some time to initialise CookieStorage

itrestian commented 6 years ago

Do any of the suggestions fixed this issue?

ynnr85 commented 6 years ago

Any solution about it? I have a #codal-ksharma similar situation: When I try to get the session using var cognitoUser = userPool.getCurrentUser();, I am getting null.

My current user was registered with this option disabled. IDK if this detail could be important. I add Storage: new AWSCognito.CognitoIdentityServiceProvider.CookieStorage({domain: CognitoUtil._DOMAIN}) after that.

My current authenticate function

authenticate(username: string, password: string, callback: CognitoCallback) {
        console.log('UserLoginService: starting the authentication');
        // Need to provide placeholder keys unless unauthorised user access is enabled for user pool
        AWSCognito.config.update({ accessKeyId: 'anything', secretAccessKey: 'anything' });

        const authenticationData = {
            Username: username,
            Password: password,
        };
        const authenticationDetails = new AWSCognito.CognitoIdentityServiceProvider.AuthenticationDetails(authenticationData);

        const userData = {
            Username: username,
            Pool: this.cognitoUtil.getUserPool(),
            Storage: new AWSCognito.CognitoIdentityServiceProvider.CookieStorage({domain: CognitoUtil._DOMAIN})
        };

        console.log('UserLoginService: Params set...Authenticating the user');
        const cognitoUser = new AWSCognito.CognitoIdentityServiceProvider.CognitoUser(userData);
        console.log('UserLoginService: config is ' + AWS.config);
        cognitoUser.authenticateUser(authenticationDetails, {
            newPasswordRequired: function (userAttributes, requiredAttributes) {
                callback.cognitoCallback(`User needs to set password.`, null);
            },
            onSuccess: function (result) {
                const logins = {};
                logins['cognito-idp.' +
                    CognitoUtil._REGION +
                    '.amazonaws.com/' +
                    CognitoUtil._USER_POOL_ID] =
                    result.getIdToken().getJwtToken();

                // Add the User's Id Token to the Cognito credentials login map.
                AWS.config.credentials = new AWS.CognitoIdentityCredentials({
                    IdentityPoolId: CognitoUtil._IDENTITY_POOL_ID,
                    Logins: logins
                });

                console.log('UserLoginService: set the AWS credentials - ' + JSON.stringify(AWS.config.credentials));
                console.log('UserLoginService: set the AWSCognito credentials - ' + JSON.stringify(AWSCognito.config.credentials));
                AWS.config.credentials.get(function (err) {
                    if (!err) {                      
                        callback.cognitoCallback(null, result);
                    } else {
                        callback.cognitoCallback(err.message, null);
                    }
                });

            },
            onFailure: function (err) {
                callback.cognitoCallback(err.message, null);
            },
        });
    }

Some of my get methods:

getUserPool() {
        return new AWSCognito.CognitoIdentityServiceProvider.CognitoUserPool(CognitoUtil._POOL_DATA);
    }

 getCurrentUser() {
     console.log('USER POOL:-> ', this.getUserPool());
     console.log('CURRENT USER:-> ', this.getUserPool().getCurrentUser());
     return this.getUserPool().getCurrentUser();
 }

My console output to getCurrentUser()

image

Any help please?, I need cross domain session working

Thanks

ynnr85 commented 6 years ago

I know where the problem is. Debuggin amazon-cognito-identity.js you can see that the cookies are created secured using this.secure = true; as you can see in the image, so if you are testing your app in a non secure environment (http) the cookies will not be transmited. In my case I was using Angular, and the compiled code was served over http in development mode.

The solution is when you pass the Storage value iniitilize secure parameter as false

Storage: new AWSCognito.CognitoIdentityServiceProvider.CookieStorage({ domain: CognitoUtil._DOMAIN, secure: false })

Other important thing is this library uses as part of the cookie key name the app cientId this.pool.getClientId() so if all your subdomains are different apps you must enter e common App Client Id defined in the Pool, if not the library will not get the cookies because the key will no match. @itrestian I thinks this is a bug that must be fixed, because the cookies must work over multiple apps with different subdomains and different Client Ids too.

selection_024

I hope this solution can help you.

kanomkrub commented 6 years ago

Storing cognito token in cookiestorage may raise another problem since browser will set cookies as http header and you may get 400 bad request because header are too long. I use aws s3 static host and got this problem.