using YUI uploader / authentication_token set but still error / session issue?

Hi,

Two questions. Or three. Several issues at once.

I'm using the YUI uploader with Rails, or at least I'm trying..
(http://developer.yahoo.com/yui/uploader/)

[ABOUT: The YUI uploader is a Flash-uploader, which is invisble on the
page and is controlled by Javascript. It is used to asynchronously
upload files from a webpage. Because it's Flash, it can produce
reliable progress messages WITHOUT involving the server.]

I create a normal form using <%- form_for(@video, :html =>
{ :multipart => true) do |f| -%>

In Javascript I fill an object with the contents of the created form
fields. I also include _session_id as POST variable, because Flash has
a bug and uses MS IE cookies even when run in side Firefox - so I can
forget about using cookie based session for this file upload. However,
this seems to fail (see below, log of webserver), the session info
seems lost and therefore my auth.token question below may already be
answered? But how DO I get the session established correctly if I
don't have the session cookie available in this POST?

var postvars = {
  video: [],
  authenticity_token: "<%= form_authenticity_token %>",
  _session_id: ""
};

//...code to fill video[] with the form_for field input field
contents...
//like this: postvars.video["name"] =
document.forms[1].elements["video[name]"].value;

uploaderSWF.uploadAll('/videos', "POST", postvars,
"video[uploaded_data]");

This causes the uploader (or it should) to perform the exact same POST
operation the form would generate in the web browser.

TWO ISSUES:

One, I get an error about a wrong authenticity token. How is this
possible, since I'm including it?
Okay, so I exempted the receiving method from forgery_protection for
further testing.
Two, I don't see the video array variables posted! Rails created
<input name="video[name]"...> style form fields. I tried to recreate
them using the above JS video array in postvars. I can't think of any
other way, unfortunately. Okay, while writing this it dawns on me why
this fails, for the browser this is just a string ("video[name]"), and
if the Flash does not produce such strings when doing the POST...

SERVER LOG OF REQUEST

Processing VideosController#create (for 127.0.0.1 at 2008-05-14
13:32:01) [POST]
  Session ID: 2a721552e475206033975ece7a440b35
  Parameters: {"Filename"=>"TXT",
"_session_id"=>"BAh7CToMY3NyZl9pZCIlODRjODFkNjg1ZjBlNjFmNjY1MjVmMmUwZjUzNjA3%250AMmU6DnJldHVybl90bzA6DHVzZXJfaWRpAiYIIgpmbGFzaElDOidBY3Rpb25D
%250Ab250cm9sbGVyOjpGbGFzaDo6Rmxhc2hIYXNoewAGOgpAdXNlZHsA--579a97d93618e59bddba08d758f93d0ae6c5b501",
"authenticity_token"=>"a2061d419e4b3be9452fcb78cf4aeaa8ba02c17c",
"action"=>"create", "Upload"=>"Submit Query", "controller"=>"videos",
"YUIuploader"=>"1",
"video"=>{"uploaded_data"=>#<ActionController::UploadedStringIO:
0xb69da3e4>}}
Redirected to http://localhost:3000/session/new
Filter chain halted as
[#<ActionController::Filters::ClassMethods::SymbolFilter:0xb697d8ec
@filter=:login_required>] rendered_or_redirected.
Completed in 0.00063 (1599 reqs/sec) | DB: 0.00277 (443%) 0 queries |
302 Found [http://localhost/videos]

Thanks!
Michael

In Javascript I fill an object with the contents of the created form
fields. I also include _session_id as POST variable, because Flash has
a bug and uses MS IE cookies even when run in side Firefox - so I can
forget about using cookie based session for this file upload. However,
this seems to fail (see below, log of webserver), the session info
seems lost and therefore my auth.token question below may already be
answered? But how DO I get the session established correctly if I
don’t have the session cookie available in this POST?

You can retain the session using any Flash based uploader, you can work around it by creating some kind of temporary authentication value through an ajax call before sending over your video via the Flash uploader, then verify that to see if the upload is legit. Turn sessions off (or don’t check for logged_in?) for that action.

var postvars = {
video: [],
authenticity_token: “<%= form_authenticity_token %>”,
_session_id: “”
};

//…code to fill video[] with the form_for field input field
contents…
//like this: postvars.video[“name”] =
document.forms[1].elements[“video[name]”].value;

uploaderSWF.uploadAll(’/videos’, “POST”, postvars,
“video[uploaded_data]”);

This causes the uploader (or it should) to perform the exact same POST
operation the form would generate in the web browser.

TWO ISSUES:

One, I get an error about a wrong authenticity token. How is this
possible, since I’m including it?
Okay, so I exempted the receiving method from forgery_protection for
further testing.
Two, I don’t see the video array variables posted! Rails created
<input name=“video[name]”…> style form fields. I tried to recreate
them using the above JS video array in postvars. I can’t think of any
other way, unfortunately. Okay, while writing this it dawns on me why
this fails, for the browser this is just a string (“video[name]”), and
if the Flash does not produce such strings when doing the POST…

Why not just use Form.serialize(formelement, true) to serialize the form to a hash (that’s what the true does) and merge that (using prototype hash’s .merge function) with the authenticity token. It could also well be that the authenticity_token is tied to the active session, and since Flash doesn’t retain sessions, you might just have to settle with deactivating it for that action.

Best regards

Peter De Berdt

If you use the cookie store then it's base on session[:crsf_id]. If not it's based on the session_id. I know nothing about flash, but if flash isn't including the cookie that ties the user to a session (or that is the session in the cookie store case) then the request from forgery stuff won't be happy

Fred

The question is this (or one of the onces I had/have), to summarize my
long posting:

If I submit a form back to Rails, and for THIS "post"-operation
cookies are not send, what name would a hidden input form element have
to have for rails to recognize the session? After all, rails by
default uses not just cookies to recognize a session, IMHO? I should
be able to send the session ID back to rails WITHOUT a cookie, but
how? What is the name of the parameter? I tried _session_id (found
somewhere, that this would be this parameter name I'm looking for),
but it does not work and rails creates a new session instead of using
this ID.

The question is this (or one of the onces I had/have), to summarize my
long posting:

If I submit a form back to Rails, and for THIS "post"-operation
cookies are not send, what name would a hidden input form element have
to have for rails to recognize the session? After all, rails by
default uses not just cookies to recognize a session, IMHO? I should
be able to send the session ID back to rails WITHOUT a cookie, but
how? What is the name of the parameter? I tried _session_id (found
somewhere, that this would be this parameter name I'm looking for),
but it does not work and rails creates a new session instead of using
this ID.

That is turned off by default. I'm also guessing it wouldn't work with
the cookie store.
This is controlled by the cookie_only option, which you can set in
environment.rb along with the other session stuff:

config.action_controller.session = { :cookie_only => false , ...}
You can also set the name of the parameter containing the session_id
there.

Fred

Dear michael:

     I'm Edward from Taipei,Taiwan and I am currently using the YUI
uploader with rails, too. Just want you to know that don't forget the
spirit of Rails:"Keep it simple!"

     To use YUI uploader with Rails is very simple. First, don't mind
the "authenticity_token". All you have to do is simply change a bit code
in your "application.rb":

     protect_from_forgery :except => :your_upload_action

     So, the rails won't ask you to post the "authenticity_toke"
varable. What is more, you don't have to care about the session issues
because file upload has nothing to do with sessions.

     Here is my controller used to handle multiple file upload with YUI
uploader:

  def your_upload_action

      File.open("#{RAILS_ROOT}/public/" +
params[:Filedata].original_filename, "wb") do |f|
      f.write(params[:Filedata].read)
      end
  end

     Try yourself, good luck :slight_smile:

                                    Netloner

Hi,

Two questions. Or three. Several issues at once.

I'm using the YUI uploader with Rails, or at least I'm trying..
(http://developer.yahoo.com/yui/uploader/)

[ABOUT: The YUI uploader is a Flash-uploader, which is invisble on the
page and is controlled by Javascript. It is used to asynchronously
upload files from a webpage. Because it's Flash, it can produce
reliable progress messages WITHOUT involving the server.]

I create a normal form using <%- form_for(@video, :html =>
{ :multipart => true) do |f| -%>

  ==> There is no need for a form in your view. YUI uploader will submit
file by itself.

var postvars = {
  video: [],
  authenticity_token: "<%= form_authenticity_token %>",
  _session_id: ""
};

  ==> in application.rb, try

        "protect_from_forgery :except => :your_upload_action"

      Then there is no need for your postvars.