I've been flirting with Adobe AIR and decided to build an AIR AJAX- based client for my Heroku app (http://poetry.heroku.com). The client would be used to write poems and an AJAX request would call create. I ran in to some trouble, however. I had a very hard time finding documentation on authenticating with AJAX, and then once I solved that problem I had some issues with acts_as_authenticated not handling the authentication. Here are some tips, in case you attempt to go through the same pain.
If you know better ways to do this, I'm all ears. I Googled for hours. Step 1 - Basic HTTP Authentication in AJAX Note: this is an AIR app, but AIR pretty much just lets you do straight HTML and javascript so this is un-molested Prototype. You need to install JS to do base64 encoding. Check out http://coderseye.com/2007/how-to-do-http-basic-auth-in-ajax.html. <script src="lib/webtoolkit.base64.js" type="text/javascript"></ script> function make_base_auth(username, password) { var tok = username + ':' + password; var hash = Base64.encode(tok); return "Basic " + hash; } Then, you need to add an Authorization header to your requestHeaders parameters in the Ajax.Request Prototype call. requestHeaders: { Accept: "application/xml", Authorization: make_base_auth('username', 'password') }, Step 2 - Controller XHR? Check The parameter style from the AJAX request differs from my form submission. I can probably improve this so the check is unnecessary but watch out for cases where your AJAX request does not provide sufficient parameters compared to your normal forms. if request.xhr? @poem = Poem.new params[:title].empty? ? @poem.title = 'Untitled' : @poem.title = params[:title] @poem.body = params[:body] @poem.user = current_user else @poem = Poem.new(params[:poem]) end Also, I had to unprotect the controller from forgery because of the authenticity token. I've heard that protect_from_forgery only works against very weak forgery attempts, so I'm not too upset about this. protect_from_forgery :except => :create Step 3 - Modify Acts_As_Authenticated I had to change the login_required filter to recognize the xhr and use basic authentication, which is what the AJAX call provides. Notice that I check not only for xhr but also for the specific controller and action because I don't want to mess up the login behavior for any other xhr I use in my app (like tagging, comments, etc.). def login_required if request.xhr? && (request.request_uri == '/poems/create') self.current_user = authenticate_with_http_basic { |u, p| User.authenticate(u, p) || :false if u && p } logged_in? && authorized? ? true : access_denied else username, passwd = get_auth_data self.current_user ||= User.authenticate(username, passwd) || :false if username && passwd logged_in? && authorized? ? true : access_denied end end I also added another format to access_denied to handle javascript. Not sure if this helps or not, but saw it recommended on a website. I'll need to revisit this to make sure I'm handling errors as best as I can. accepts.js do render(:update) { |page| page.redirect_to(:controller => '/ account', :action => 'login') } end Hope all this helps you one day. I like AIR, so I hope to get in to more of this. Using my (meager) HTML and JS skills to build proper desktop apps with self-upgrade capabilities and other niceties is... nice. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Heroku" group. To post to this group, send email to [email protected] To unsubscribe from this group, send email to [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/heroku?hl=en -~----------~----~----~----~------~----~------~--~---
