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.

Mohit Raheja
Hi DanielYou can send the

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

Vote: 
Vote up!
Vote down!

Points: 1

You voted ‘up’


Daniel Chaves
Thanks Mohit!First, where do

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.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mohit Raheja
Hi DanielRight now, how you

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Daniel Chaves
Hi, Mohit. Thank you for

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!

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mohit Raheja
Hi Daniel,Well i don't think

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Daniel Chaves
I have an api built in Rails,

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.co...

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mohit Raheja
Hi DanielThanks for the

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

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Daniel Chaves
Hi Mohit, thanks for the help

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.

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mohit Raheja
Hi DanielYeah sending the

Hi Daniel

Yeah sending the token inside the URL is not secure that's why post type services are proffered. You can go for the post type web service as it secure.

And let me try once for the token then i will get back to you regarding this issue, as i haven't faced such scenario till now.

Thanks

Mohit Raheja

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Mark van Rijbroek
Hello Mohit Raheja,I'm

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?

Vote: 
Vote up!
Vote down!

Points: 0

You voted ‘up’


Log in to post comments