ConnectyCube / connectycube-flutter-samples

Code samples for Flutter, based on ConnectyCube platform
https://developers.connectycube.com/flutter/
Apache License 2.0
85 stars 90 forks source link

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

Closed jostney closed 3 months ago

jostney commented 6 months ago

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 commented 6 months ago

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

TatankaConCube commented 5 months ago

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 commented 5 months ago

@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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

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 commented 5 months ago

@banshiAnton can assist here, I will ask him

banshiAnton commented 5 months ago

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

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

jostney commented 5 months ago

Sent it, waiting. Thanks

eznix86 commented 4 months ago

Same issue on my side,

TatankaConCube commented 4 months ago

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 support@connectycube.com

eznix86 commented 4 months ago

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 support@connectycube.com

I already sent. No answer yet.

TatankaConCube commented 4 months ago

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

eznix86 commented 4 months ago

@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 commented 4 months ago

will ask the support team to do it

TatankaConCube commented 4 months ago

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

eznix86 commented 4 months ago

Hi,

Yes, I already did (spent 5 hours on google), it is the same thing, but with modern PHP.

I tested in nodeJS also, still the same issue. Even if I write it manually. Scroll down completely to see the code. I even tried a bare http request. Same result.

To explain: http_build_query does the same thing as the github link it concatenates with &. I even tried it manually.

On Mon, Feb 26, 2024 at 5:53 PM TatankaConCube @.***> wrote:

@eznix86 https://github.com/eznix86 have you seen the PHP example for session creation here https://github.com/ConnectyCube/connectycube-reactnative-samples/issues/13#issuecomment-540114109 ?

— Reply to this email directly, view it on GitHub https://github.com/ConnectyCube/connectycube-flutter-samples/issues/323#issuecomment-1964200494, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGKSW2X22RDXVLISZW55XUTYVSHWJAVCNFSM6AAAAABBH3SLIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRUGIYDANBZGQ . You are receiving this because you were mentioned.Message ID: @.*** com>

TatankaConCube commented 4 months ago

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

TatankaConCube commented 4 months ago

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 commented 4 months ago

Yes

This is the results:

application_id=7578&auth_key=VM-JanUakwoI&nonce=6210&timestamp=1708956650&user[login]=demo5&user[password]=password

Side note: I am not generating an application session, what I want is a user session. The application session works well.

On Mon, Feb 26, 2024 at 6:04 PM TatankaConCube @.***> wrote:

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

— Reply to this email directly, view it on GitHub https://github.com/ConnectyCube/connectycube-flutter-samples/issues/323#issuecomment-1964223507, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGKSW2XZVBRACEW2O2YONALYVSJADAVCNFSM6AAAAABBH3SLIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRUGIZDGNJQG4 . You are receiving this because you were mentioned.Message ID: @.*** com>

TatankaConCube commented 4 months ago

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 commented 4 months ago

@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 commented 4 months ago

Hey,

I am back. Finally, You are right, the issue was with the http_build_query which was doing some special encoding.

On Mon, Feb 26, 2024 at 7:09 PM TatankaConCube @.***> wrote:

@eznix86 https://github.com/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

— Reply to this email directly, view it on GitHub https://github.com/ConnectyCube/connectycube-flutter-samples/issues/323#issuecomment-1964371070, or unsubscribe https://github.com/notifications/unsubscribe-auth/AGKSW2RBI6YRDB4UYSVMLALYVSQSRAVCNFSM6AAAAABBH3SLIOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNRUGM3TCMBXGA . You are receiving this because you were mentioned.Message ID: @.*** com>