1

我正在尝试通过使用Devise但无法弄清楚如何将 AMF 请求映射到 Devise::SessionsController#New 的 adobe flex 应用程序登录到我的 Rails 应用程序。我尝试了以下

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

当我单击“开始”按钮时,rails 报告以下内容

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

欢迎任何建议。谢谢

4

2 回答 2

2

首先,AMF 确实支持设置和发送 cookie 数据。不幸的是,有相当多的旧版浏览器和过分热心的防病毒软件的组合仅针对 AMF 流量去除 cookie。为避免这些问题,我公司所有受保护的 AMF 调用都需要会话 ID 进行身份验证。我们在 Flash 中使用 ExternalInterface 从 cookie 中获取用户的会话 ID,并将其作为所有 AMF 调用的第一个参数发送。通过这种方式,我们避免了与 cookie 和 AMF 相关的所有问题。

也就是说,由于 Devise 和 RubyAMF 的工作方式,Devise 无法获取您通过 AMF 发送的用于登录的用户名和密码。因此,即使您将请求发送到正确的控制器和操作,它仍然会失败。

原因是 Devise 所基于的 Warden 从机架请求中提取用户名和密码。RubyAMF 使用 Rails 请求和响应对象,并在调用控制器时修改 Rails 请求的参数哈希。所以当你向 login 动作发出 RubyAMF 请求时,Devise 去登录用户,Warden 检查原始机架请求并发现乱码,登录失败。

于 2010-09-22T13:01:22.043 回答
0

我找到了一个解决方法,我希望得到一些人的意见,尤其是warhammerkid

在我们的例子中,会话 ID 通过我们的 Flex 应用程序来回传输,但是session当它通过 RubyAMF 到达我们的 Rails 控制器时,Rails 哈希是空的。因此,如果我们成功恢复会话,我会强制用户登录。(当然,其他会话数据需要手动恢复。)

def authenticate_user!
  recover_session unless user_signed_in?

  super
end

def recover_session
  session_id = request.cookies['_crm_session'] # Use your session key here
  return unless session_id

  verifier = ActiveSupport::MessageVerifier.new(Rails.application.config.secret_token)
  signed_session = verifier.verify(session_id)

  user_id = signed_session['warden.user.user.key'].andand[1].andand[0]
  return unless user_id

  sign_in(User.find(user_id))

rescue ActiveSupport::MessageVerifier::InvalidSignature
end

其中部分内容特定于我们的应用程序......您需要对其进行修改以满足您的需求。

于 2012-03-20T17:38:31.710 回答