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

Issue with ConnectyCube User Session Token Creation - "Unexpected Signature" #323

Closed
jostney opened this issue Dec 31, 2023 · 24 comments
Closed

Comments

@jostney
Copy link

jostney commented Dec 31, 2023

I am currently facing an issue when attempting to create a user session token using the ConnectyCube REST API. The server consistently returns an "unexpected signature" error, despite the fact that the signature generation appears to work correctly for other actions, such as creating an app session token.

Here's the method I use to generate the signature:

const getSignature = () => {
  const nonce = Math.floor(Math.random() * 1000000);
  const timestamp = Math.floor(Date.now() / 1000);
  const stringForSignature = `application_id=${config.applicationId}&auth_key=${config.authKey}&nonce=${nonce}&timestamp=${timestamp}`;
  const signature = crypto.createHmac('sha1', config.authSecret).update(stringForSignature).digest('hex');
  return { signature: signature, timestamp: timestamp, nonce: nonce };
}

The signature generation seems correct, as evidenced by the successful creation of an app session token:

const getAppSessionToken = async () => {
  const signature = getSignature();
  const response = await axios.post(
    'https://api.connectycube.com/session', {
    'application_id': config.applicationId,
    'auth_key': config.authKey,
    'nonce': signature.nonce,
    'timestamp': signature.timestamp,
    'signature': signature.signature
  }, { headers: { 'Content-Type': 'application/json' } });
  return response.data.session.token;
}

However, the same signature, when used to create a user session token, leads to the server responding with an "unexpected signature" error:

const createSessionWithLogin = async (emailAddress, password) => {
  const signature = getSignature();
  return await axios.post(
    'https://api.connectycube.com/session',
    {
      'application_id': config.applicationId,
      'auth_key': config.authKey,
      'nonce': signature.nonce,
      'timestamp': signature.timestamp,
      'signature': signature.signature,
      'user': {
        'email': emailAddress,
        'password': password
      }
    },
    {
      headers: {
        'Content-Type': 'application/json'
      }
    }
  );
}

I would expect the user session token creation to be successful, similar to the app session token creation. However, the server consistently returns an "unexpected signature" error for user session token creation.

@jostney
Copy link
Author

jostney commented Dec 31, 2023

Sorry for asking it on flutter repo but i could not find proper place to ask it

@TatankaConCube
Copy link
Contributor

according to the server documentation, the parameters for the generation of the signature should be placed in alphabetical order. it means when you add the user to the signature this parameter should be placed there in the alphabetical order too.

@TatankaConCube
Copy link
Contributor

@jostney I meant the stringForSignature with the user should look next:

const stringForSignature = `application_id=${config.applicationId}&auth_key=${config.authKey}&nonce=${nonce}&timestamp=${timestamp}&user[email]=${emailAddress}&user[password]=${password}`;

@jostney
Copy link
Author

jostney commented Jan 2, 2024

In docs, the last two params(&user[email]=${emailAddress}&user[password]=${password}) did not mention.

By the way, i modifed stringForSignature as you did, still having same error when calling createSessionWithLogin

const getSignatureForUserSession = (emailAddress, password) => {
  const nonce = Math.floor(Math.random() * 1000000);
  const timestamp = Math.floor(Date.now() / 1000);
  const stringForSignature = `application_id=${config.applicationId}&auth_key=${config.authKey}&nonce=${nonce}&timestamp=${timestamp}&user[email]=${emailAddress}&user[password]=${password}`;
  const signature = crypto.createHmac('sha1', config.authSecret).update(stringForSignature).digest('hex');
  return { signature: signature, timestamp: timestamp, nonce: nonce };
}

const createSessionWithLogin = async (login, password) => {
  const signature = getSignatureForUserSession(login, password);
  
  const requestData = {
    'application_id': config.applicationId,
    'auth_key': config.authKey,
    'nonce': signature.nonce,
    'signature': signature.signature,
    'timestamp': signature.timestamp,
    "user": {
      "email": login,
      "password": password
    }
  };

  return await axios.post(
    'https://api.connectycube.com/session',
    requestData,
    {
      headers: {
        'Content-Type': 'application/json'
      }
    }
  );
};

@TatankaConCube
Copy link
Contributor

In docs, the last two params(&user[email]=${emailAddress}&user[password]=${password}) did not mention.

the list of available parameters for session creation is provided in that doc at the table bottom

@jostney
Copy link
Author

jostney commented Jan 2, 2024

Who can assist me about this from back-end team ? In my latest answer i did all required things but still getting unexpected signature

@TatankaConCube
Copy link
Contributor

@banshiAnton can assist here, I will ask him

@banshiAnton
Copy link
Contributor

Hi @jostney
Can you please send stringForSignature before and after hashing and requestData
Send this on our support email [email protected]
because this logs can contain sensitive account information

and double check your config (application_id/auth_key/auth_secret)

@jostney
Copy link
Author

jostney commented Jan 3, 2024

Sent it, waiting. Thanks

@eznix86
Copy link

eznix86 commented Feb 26, 2024

Same issue on my side,

@TatankaConCube
Copy link
Contributor

Same issue on my side

@eznix86 please share here your string to signing and the body of the request. or you can send this info to our support team's e-mail [email protected]

@eznix86
Copy link

eznix86 commented Feb 26, 2024

Same issue on my side

@eznix86 please share here your string to signing and the body of the request. or you can send this info to our support team's e-mail [email protected]

I already sent. No answer yet.

@TatankaConCube
Copy link
Contributor

@eznix86 in the provided info, the string you want to subscribe is absent, please provide all required information

@eznix86
Copy link

eznix86 commented Feb 26, 2024

@eznix86 in the provided info, the string you want to subscribe is absent, please provide all required information

Please reply to my email. I would happy to share code snippets.

@TatankaConCube
Copy link
Contributor

will ask the support team to do it

@TatankaConCube
Copy link
Contributor

@eznix86 have you seen the PHP example for session creation here?

@eznix86
Copy link

eznix86 commented Feb 26, 2024 via email

@TatankaConCube
Copy link
Contributor

have you ordered your parameters in line 103 in your code in the right way?

@TatankaConCube
Copy link
Contributor

TatankaConCube commented Feb 26, 2024

does this parameters contains all data from the body request (except signature)? could you provide the ready for signing string in the raw formate before signing?

@eznix86
Copy link

eznix86 commented Feb 26, 2024 via email

@TatankaConCube
Copy link
Contributor

sorry, but I'm not well experienced in the PHP, but the Dart code below works in my case, please check the differences and additionaly please check the time on your local machine where you run the code

    Map<String, dynamic> parameters = request.params;

    StringBuffer keyValueSortedString = StringBuffer();
    Map<String, String> sortedParams = SplayTreeMap.from(parameters);

    for (String key in sortedParams.keys) {
      keyValueSortedString.write("$key=${sortedParams[key]}&");
    }

    String signString = keyValueSortedString.toString();
    signString = signString.substring(0, signString.length - 1);

    String key = CubeSettings.instance.authorizationSecret!;
    log('Sign string : $signString');

    List<int> messageBytes = utf8.encode(signString);
    List<int> keyBytes = utf8.encode(key);

    Hmac hmac = Hmac(sha1, keyBytes);
    Digest digest = hmac.convert(messageBytes);

    String signature = digest.toString();
CB-SDK: : Sign string : application_id=476&auth_key=PDZjPBzAO8WPfCp&nonce=911182476&timestamp=1708958827&user[login]=flutter_sdk_tests_user&user[password]=flutter_sdk_tests_user
CB-SDK: : =========================================================
=== REQUEST ==== 20db44b9-a879-4dcd-af97-80227f2a3056 ===
REQUEST
  POST https://api.connectycube.com/session 
HEADERS
  {Content-type: application/json, ConnectyCube-REST-API-Version: 0.1.1, CB-SDK: Flutter 2.11.2, CB-Token: }
BODY
  {"application_id":"476","auth_key":"PDZjPBzAO8WPfCp","nonce":"911182476","timestamp":"1708958827","signature":"bd31b16e034197c187ac9ade6f4df65513f744d1","user":{"login":"flutter_sdk_tests_user","password":"flutter_sdk_tests_user"}}

CB-SDK: : *********************************************************
*** RESPONSE *** 201 *** 20db44b9-a879-4dcd-af97-80227f2a3056 ***
HEADERS
  {cb-token-expirationdate: 2024-02-26 16:47:08 UTC, connection: keep-alive, date: Mon, 26 Feb 2024 14:47:08 GMT, strict-transport-security: max-age=15768000; includeSubDomains, content-length: 674, access-control-expose-headers: CB-Token-ExpirationDate, Date, content-type: application/json; charset=utf-8, server: nginx/1.25.0}
BODY
  {"session":{"created_at":"2024-02-26T14:47:08.627Z","updated_at":"2024-02-26T14:47:08.627Z","application_id":476,"token":"3C50709786E66B78C618850B6E7D00B359B9","nonce":911182476,"ts":1708958827,"user_id":2325293,"id":2325293,"user":{"_id":"60926149f8550e007e061943","id":2325293,"created_at":"2020-10-28T13:29:49Z","updated_at":"2024-01-02T10:43:52Z","last_request_at":"2024-01-02T10:43:52Z","timezone":null,"login":"flutter_sdk_tests_user","email":null,"full_name":"Flutter SDK Tests User","phone":null,"website":null,"twitter_id":null,"external_user_id":null,"facebook_id":null,"custom_data":null,"user_tags":"tag1,tag2","avatar":null,"external_id":null,"is_guest":null}}}

@TatankaConCube
Copy link
Contributor

@eznix86 could you please share the request value before the return hash_hmac('sha1', $request, config("services.connectycube.secret")); I suppos the function http_build_query adds some symbols to the string instead of '[' and ']'. Try to use the example I shared before

@eznix86
Copy link

eznix86 commented Feb 26, 2024 via email

@DaveLomber
Copy link
Contributor

As for the reference, this is a working create session with user example in JS https://github.com/ConnectyCube/create-session-example/tree/main/create-session-example-js

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

No branches or pull requests

5 participants