10 Replies Latest reply on Aug 14, 2013 4:50 AM by Mark van Rijbroek

    How to send params from Rhodes and set custom headers in Rhoconnect?

      Hello there! Newbie talking...

       

      I built an app that will consume a REST webservice (buitl in Rails) through Rhoconnect. Once I cannot controll sessions in the webservice, I authenticate each requests checking a token sent in its' header. My question is:

       

         * I will store the user's token in the Rhodes app, so I need to send it as a parameter to Rhoconnect. How can I do that?

         * When I receive the token param in Rhoconnect, how do I insert it in the header of the request I will send to webservice?

       

      Thanks in advance.

        • Re: How to send params from Rhodes and set custom headers in Rhoconnect?
          Mohit Raheja

          Hi Daniel

           

          You can send the parameters to rhoconnect app by passing them in query string as:

           

          variable= '[{"value":"'+$sessionID+'"}]'

          SyncEngine.dosync_source(ModelName.get_source_name,false,"query=#{variable}")

           

          Here you can replace the variable with your variable name in which you have stored the session id. In query value is always send as a hash in rhoconnect application.

          You will get these values in the query method of your source adapter.

          There you have to parse the values to get the hash like:

          @data = JSON.parse("#{params}")

                #fetching the value from array

                @data1 = @data[0]

           

          You will get the hash in @data1 so you can use it easily.

           

          And will you please tell me which type of web services are you using (get or post) so that i will be able to help you for your second scenario.

           

          Thanks

          Mohit Raheja

          1 of 1 people found this helpful
            • Re: How to send params from Rhodes and set custom headers in Rhoconnect?

              Thanks Mohit!

               

              First, where do I put this code "SyncEngine.dosync_source"? In the Rhodes' model? Sorry, I have few experience developing in Rhodes.

               

              Second, I use the webservice to GETs and POSTs, but I check in each request (for both) the 'token' parameter, so that I can authenticate the user which is requesting the action.

                • Re: How to send params from Rhodes and set custom headers in Rhoconnect?
                  Mohit Raheja

                  Hi Daniel

                   

                  Right now, how you are calling your source adapter? You want to send the token on some user action or in auto sync process?

                   

                  Along with that, if possible please the code of your controller file so that i will be able to help you.

                   

                  And for authenticating the user, are you logging in your rhoconnect application with the same user with which you have logged in into your back-end application or are you just bypassing the rhoconnect login?

                   

                  Thanks

                  Mohit Raheja

                    • Re: How to send params from Rhodes and set custom headers in Rhoconnect?

                      Hi, Mohit. Thank you for clearing my doubts.

                       

                      I haven't changed the auto-generated rhodes code, except uncommenting the "enable sync" on model. So, I want to send the token to Rhoconnect in the auto sync process.

                       

                      Here is the "controller.rb" file code:

                       

                      require 'rho'

                      require 'rho/rhocontroller'

                      require 'rho/rhoerror'

                      require 'helpers/browser_helper'

                       

                       

                      class SettingsController < Rho::RhoController

                        include BrowserHelper

                       

                        def index

                          @msg = @params['msg']

                          render

                        end

                       

                       

                        def login

                          @msg = @params['msg']

                          render :action => :login

                        end

                       

                       

                        def login_callback

                          errCode = @params['error_code'].to_i

                          if errCode == 0

                            # run sync if we were successful

                            WebView.navigate Rho::RhoConfig.options_path

                            SyncEngine.dosync

                          else

                            if errCode == Rho::RhoError::ERR_CUSTOMSYNCSERVER

                              @msg = @params['error_message']

                            end

                             

                            if !@msg || @msg.length == 0  

                              @msg = Rho::RhoError.new(errCode).message

                            end

                           

                            WebView.navigate ( url_for :action => :login, :query => {:msg => @msg} )

                          end 

                        end

                       

                       

                        def do_login

                          if @params['login'] and @params['password']

                            begin

                              SyncEngine.login(@params['login'], @params['password'], (url_for :action => :login_callback) )

                              @response['headers']['Wait-Page'] = 'true'

                              render :action => :wait

                            rescue Rho::RhoError => e

                              @msg = e.message

                              render :action => :login

                            end

                          else

                            @msg = Rho::RhoError.err_message(Rho::RhoError::ERR_UNATHORIZED) unless @msg && @msg.length > 0

                            render :action => :login

                          end

                        end

                       

                        def logout

                          SyncEngine.logout

                          @msg = "You have been logged out."

                          render :action => :login

                        end

                       

                        def reset

                          render :action => :reset

                        end

                       

                        def do_reset

                          Rhom::Rhom.database_full_reset

                          SyncEngine.dosync

                          @msg = "Database has been reset."

                          redirect :action => :index, :query => {:msg => @msg}

                        end

                       

                        def do_sync

                          SyncEngine.dosync

                          @msg =  "Sync has been triggered."

                          redirect :action => :index, :query => {:msg => @msg}

                        end

                       

                        def sync_notify

                                  status = @params['status'] ? @params['status'] : ""

                       

                                  # un-comment to show a debug status pop-up

                                  #Alert.show_status( "Status", "#{@params['source_name']} : #{status}", Rho::RhoMessages.get_message('hide'))

                       

                                  if status == "in_progress"

                                    # do nothing

                                  elsif status == "complete"

                            WebView.navigate Rho::RhoConfig.start_path if @params['sync_type'] != 'bulk'

                                  elsif status == "error"

                       

                            if @params['server_errors'] && @params['server_errors']['create-error']

                              SyncEngine.on_sync_create_error(

                                @params['source_name'], @params['server_errors']['create-error'].keys, :delete )

                            end

                       

                       

                            if @params['server_errors'] && @params['server_errors']['update-error']

                              SyncEngine.on_sync_update_error(

                                @params['source_name'], @params['server_errors']['update-error'], :retry )

                            end

                           

                            err_code = @params['error_code'].to_i

                            rho_error = Rho::RhoError.new(err_code)

                           

                            @msg = @params['error_message'] if err_code == Rho::RhoError::ERR_CUSTOMSYNCSERVER

                            @msg = rho_error.message unless @msg && @msg.length > 0  

                       

                       

                            if rho_error.unknown_client?( @params['error_message'] )

                              Rhom::Rhom.database_client_reset

                              SyncEngine.dosync

                            elsif err_code == Rho::RhoError::ERR_UNATHORIZED

                              WebView.navigate(

                                url_for :action => :login,

                                :query => {:msg => "Server credentials are expired"} )               

                            elsif err_code != Rho::RhoError::ERR_CUSTOMSYNCSERVER

                              WebView.navigate( url_for :action => :err_sync, :query => { :msg => @msg } )

                            end   

                                end

                        end 

                      end

                       

                       

                       

                      Let's say that, right now, I'm bypassing the rhoconnect login. I'm just using the token to interact with the webservice.

                       

                      Thank you very much!

                        • Re: How to send params from Rhodes and set custom headers in Rhoconnect?
                          Mohit Raheja

                          Hi Daniel,

                           

                          Well i don't think so that you will be able to send the parameters in auto-sync. For sending the parameters in rhoconnect you have to do a manual-sync.

                          Do you want to authenticate the user while fetching the data from back-end?

                          Can you please give me a brief idea about your scenario?

                           

                          Thanks

                          Mohit Raheja

                            • Re: How to send params from Rhodes and set custom headers in Rhoconnect?

                              I have an api built in Rails, with which I interact via JSON. Initially I

                              did it to interact with a desktop app. In this api, I'm not able to login

                              once and keep the session alive until the client is disconnected. So I did

                              the following: the user do login in the back-end and, if sucessful, the

                              service's response send a token to the desktop app. Once the app has the

                              token, it can request GETs and POSTs to the service sending the token in

                              header, no need to authenticate again and again. The back-end check the

                              token and authenticate it's own way. If the token is valid, then it

                              executes the requested action.

                               

                              That's what I want to do with my rhodes app, the differences are that the

                              user will authenticate the app only once. I will store the token to each

                              user locally. So he will login (locally) and if the login is sucessful, it

                              will be able to sync the data with rhoconnect only passing the token in

                              each trigered sync.

                               

                              In resume, I need to pass this token to Rhoconnect and in Rhoconnect I need

                              to add this param to the header of request to back-end in order to get the

                              JSON objects.

                               

                              Is it clear?

                               

                              Thank you very much.

                               

                               

                              2013/4/23 Mohit Raheja <motorola-dev@motorola-dev.hosted.jivesoftware.com>

                               

                              **

                                   Motorola Solutions Launchpad<https://developer.motorolasolutions.com/index.jspa>

                              Re: How to send params from Rhodes and set custom headers in Rhoconnect? created by Mohit

                              Raheja<https://developer.motorolasolutions.com/people/raheja.mohit51%40gmail.com>in

                              RhoMobile Discussions - View the full discussion<https://developer.motorolasolutions.com/message/9079#9079>

                               

                                • Re: How to send params from Rhodes and set custom headers in Rhoconnect?
                                  Mohit Raheja

                                  Hi Daniel

                                   

                                  Thanks for the summary. I will suggest if you are getting the token from the back-end itself then don't pass it to the rhodes application rather store it in the rhoconnect application( i.e in redis server) and at the time a sync is triggered you can easily fetch the token from the rhoconnect application.

                                   

                                  You can store the data in rhoconnect application as:

                                  Store.put_value("userName","#{@sessionID}")

                                   

                                  and you can fetch the values from there as:

                                  @id = Store.get_value("userName")

                                   

                                  By doing this way you don't have to fetch your token id from rhodes application.

                                   

                                  And for sending a token in the header you can send it inside the body part of web service.

                                  For get type service you can do it as:

                                   

                                       service_url = "#{$base}/MethodName?sessionID=" + @id

                                      #get type service call

                                      @res=RestClient.get(service_url,:content_type => :json)

                                   

                                  For post type of service you can do:

                                       service_url = "#{$base}/MethodName"

                                      #body containing username

                                      body = "#{@id}"

                                      #post type service call

                                      @res=RestClient.post(service_url,body.to_json,:content_type => :json)

                                   

                                  Hope it helps

                                   

                                  Thanks

                                  Mohit Raheja

                                    • Re: How to send params from Rhodes and set custom headers in Rhoconnect?

                                      Hi Mohit, thanks for the help. I will certainly consider this solution, but there's just two things I'd like you explain me, if you can.

                                       

                                      First: For security reasons I don't pass the token in plain URL, like a parameter (?token='xxxxxxxxxx'). I include it in the header, so that it's invisible in logs or something. That's why I wish to include it in the header of the Rhoconnect GETs and POSTs request to the back-end, instead of appending it to the service_url. Any opinion?

                                       

                                      Second: As you said, it's not possible to send params in the auto-sync from Rhodes to Rhoconnect, right? Because I had in mind the following scenario: To require to the user to connect directly to the service at the first time he opens the app in his device, an then he can get the validation token directly, and Rhodes can store it locally in the device. In the next time he open the app, it doesn't need validation again (because the token is already stored), that's why I'd wish to pass the token from Rhodes to Rhoconnect.

                                       

                                      Thank you very much for all this help.

                                      • Re: How to send params from Rhodes and set custom headers in Rhoconnect?

                                        Hello Mohit Raheja,

                                         

                                        I'm confronting the same dilemma as Daniel is.

                                        It seems to me the solution you suggest is not working the way I and Daniel would like to, considering the following scenario:

                                         

                                        I login with username1 on device 1.

                                        This user does; @id = Store.put_value("userName") on rhoconnect.

                                        So store value for UserName is now "username1".

                                         

                                        Now username2 logs in on device 2.

                                        This user also does; @id = Store.put_value("userName") on rhoconnect.

                                        So store value for UserName is now "username2".

                                         

                                        Now username1 updates a record and synchronise that.

                                        He will sync with username2... Which is not correct.

                                         

                                        Am I overlooking something?