views:

153

answers:

1

I am trying to login in to my Rails app through an adobe flex application that uses Devise but cannot figure out how to map the AMF request to Devise::SessionsController#New. I tried the following

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
           xmlns:s="library://ns.adobe.com/flex/spark" 
           xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="700" minHeight="600">
<fx:Declarations>
    <mx:RemoteObject id="deviseService" fault="onFault(event)"

                     source="Devise:SessionsController" destination="rubyamf">

        <mx:method name="new" result="onResult(event)" />

    </mx:RemoteObject>

</fx:Declarations>

<fx:Script>
    <![CDATA[
        import mx.rpc.events.ResultEvent;
        import mx.rpc.events.FaultEvent;
        import mx.rpc.Fault;   

        private function onFault(e:FaultEvent):void
        {
            resultTxt.text = e.fault.faultString;   
        }

        private function onResult(e:ResultEvent):void
        {
            resultTxt.text = e.message.toString();
        }   
    ]]>
</fx:Script>

<s:Panel title="Login" width="300" height="150" x="597" y="248" >
    <s:VGroup horizontalAlign="center" paddingLeft="5"  paddingRight="5">
        <s:HGroup paddingLeft="5" paddingRight="5">     
            <s:Label text="Username"  />
            <s:TextInput id="username" width="100" />       
        </s:HGroup>
        <s:HGroup >
            <s:Label text="Password" />
            <s:TextInput id="password" width="100" />
        </s:HGroup> 
        <s:Button id="submitLogin" label="go" click="deviseService.new.send({name: username.text, password: password.text});" />
        <s:Label id="resultTxt" />
    </s:VGroup>
</s:Panel>  

When I click the "go" button, the rails reports the following

Started POST "/rubyamf/gateway" for 127.0.0.1 at 2010-09-19 18:59:52 -0500
Rendered devise/shared/_links.erb (1.0ms)
Rendered devise/menu/_registration_items.html.erb (2.0ms)
Rendered devise/menu/_login_items.html.erb (1.0ms)
{"session_id"=>"dc95da0ed877a214ffc60eeb3f635c34", "_csrf_token"=>"9npBO2tywAK30O43rroOwMZTEC8P+kUSdjuxe2u9hxA=", "flash"=>{:alert=>"You need to sign in or sign up before continuing."}}
Rendered devise/sessions/new.html.erb within layouts/application (40.0ms)
Completed 200 OK in 176ms (Views: 69.0ms | ActiveRecord: 0.0ms)
Started POST "/rubyamf/gateway" for 127.0.0.1 at 2010-09-19 18:59:53 -0500
Sending back AMF

Any suggestions are welcomed. Thanx

A: 

First off, AMF does support setting and sending cookie data. Unfortunately, there are quite a few combinations of older browser and overzealous AntiVirus software that strip out cookies only for AMF traffic. To avoid these issues, all of my company's protected AMF calls require the session id for authentication. We use ExternalInterface in Flash to grab the user's session id from the cookie and send that as the first parameter of all AMF calls. In this way we avoid all the issues associated with cookies and AMF.

That said, because of the way that Devise and RubyAMF work, Devise cannot get the username and password that you sent through AMF to log in. So even if you sent the request to the proper controller and action it would still fail.

The reason for this is that Warden, which Devise is based off of, pulls the username and password from the rack request. RubyAMF uses Rails request and response objects and modifies the parameters hash of the Rails request when calling a controller. So when you make a RubyAMF request to the login action, Devise goes to log the user in, Warden checks the original rack request and finds gibberish, and the login fails.

warhammerkid
So I should use a different approach with ruby/rails for establishing/authenticating sessions with RubyAMF?
Joey
Or could I previously login through Devise and use the ExternalInterface to pass along the session parameters?
Joey
You'll have to decide what works best for you. The flash applications that I've developed all have corresponding websites that can handle the authentication and session setup. In that case passing the session token into flash through ExternalInterface or flash variables is relatively simple (although lookup can be a pain). Or it could be easier to write some extensions to Warden/Devise that will allow you to pass a login and password in yourself, rather than pulling from the request. I'm not too familiar with Warden, so it might not be that difficult.
warhammerkid
I have the rails session token in flex but cannot pass them into rails correctly. I am attempting to pass the sessiontokin in through a "send" service call like 'somethingService.new.send(session_id: '###')' and rails is receiving the session param in a hash as like {0=>{"session_id"=>'###')}} instead of like {"session_id"=>'###')}. Any suggestions?
Joey