mustafal / Odoo-JsonRpc-with-Flutter

A Framework for odoo mobile with Flutter
85 stars 88 forks source link

Problems when there are 2 "set-cookie" headers is same response #1

Closed joao-jeronimo closed 3 years ago

joao-jeronimo commented 4 years ago

Hello, Looks like this implementation has some problems with cookies, in particular when there are 2 "set-cookie" headers is same response from server. Just see the following code in file "lib/app/data/services/odoo_api.dart":

  _updateCookies(http.Response response) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String rawCookie = response.headers['set-cookie'];
    if (rawCookie != null) {
      _headers['Cookie'] = rawCookie;
      prefs.setString(Constants.SESSION, rawCookie);
    }
  }

Multiple set-cookie headers are in fact being concatenated in the same "rawCookie" string, separated by commas. This makes it hard to work-arround because some cookie attributed may in fact have legal commas (e.g. the Expires attribute). I found this problem because the session was being forced to terminate when I did a json RPC call to a controller - looks like in this case odoo12 send the frontend_lang cookie first, so the next request will think that the session_id was not sent. Else, there is a more fundamental problem: the client is supposed to send only the cookies, not the attributes. Only the server sends attributes.

Thank you, João Jerónimo

joao-jeronimo commented 4 years ago

One possible (and imperfect) hack:

  _updateCookies(http.Response response) async
  {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    String rawCookie = response.headers['set-cookie'];
    if (rawCookie != null)
    {
      // Hack: all cookies come in same line and this should not happen:
      // First, remove all cookie attributes - they aren't needed:
      rawCookie = rawCookie.replaceAllMapped(RegExp(r'; [^,;]+'), (match) {
        return '';
      });
      // Then convert all comma cookie separators into semicollons, adding also a trailing semicolon:
      rawCookie = rawCookie.replaceAllMapped(RegExp(r',|$'), (match) {
        return ';';
      });
      // Remove elements that aren't cookies (i.e. they don't have an equals sign):
      rawCookie = rawCookie.replaceAllMapped(RegExp(r';[^;=]+;'), (match) {
        return ';';
      });
      // Remove trailing (possibly repeated) semicolon(s):
      rawCookie = rawCookie.replaceAllMapped(RegExp(r'( *;)* *$'), (match) {
        return '';
      });
      _headers['Cookie'] = rawCookie;
      prefs.setString(Constants.SESSION, rawCookie);
      print("»» New cookie string: '"+prefs.getString(Constants.SESSION)+"' ««");
    }
  }

Regards, João Jerónimo

mustafal commented 4 years ago

@joao-jeronimo, I will look into it and get back to you

joao-jeronimo commented 4 years ago

Hello, Why not use a ready-made XML-RPC library as a base to implement this? It's more tested and the APIs much better documented than for JSON-RPC. https://www.odoo.com/documentation/13.0/webservices/odoo.html Regards, João Jerónimo

thiepwong commented 4 years ago

I am using Odoo V13, and I tried to login using this flutter project, but my odoo authenticate return without a session_id. I cannot found any session id in controller of web module. Why and How to enable the session_id? Thanks alot

mustafal commented 3 years ago

try wih new commit