Payday Loans Online Payday Loans Online

Todd Rothe : UI/UX Developer

it's pronounced rowth-ee

By 2g1c2 girls 1 cup

Flex On Rails User Authentication Quick Start Guide

Building a backend for your Flex app that handles user account creation and user authentication is not a small task. Hence the length of this ‘quick start’ guide. Ruby on Rails allowed me to provide this functionality in a relatively short time.
When your finished with this quick start guide a user of your site should be able to create a new account.

Sample project : FlexOnRailsAuthentication.zip

Required Installs
Ruby On Rails
Flex Builder 3
Local server (I’m using MAMP)

Create Your Database
Start your server
Open up your db admin tool
Create a new db called FlexOnRailsAuthentication_dev

Create Your Flex Project
Open Flex Builder and create a new flex project called FlexOnRailsAuthentication

Create The Rails App/Backend (get a drink, put your headphones on, get ready, this is it)
Open terminal
Navigate to you Flex Builder project and type

rails myBackend

terminal window
Executing this statement should trace out a bunch of ‘create’ statements
Now cd into my_backend and install the restful authentication plugin by running the following

./script/plugin install restful_authentication

If that fails try explicitly grabbing the plug as follows

./script/plugin install -r 3072 http://svn.techno-weenie.net/projects/plugins/restful_authentication/

Then use the plugin to generate the authentication scaffolding

./script/generate authenticated user sessions

In your Flex Builder app open myBackend/app/config/database.yml and modify the first entry to reflect your environment. This crucial step will provide your backend with a reference to your db. Later, when you test the form via html/browser, if things don’t work you may need to revisit this step. Mine looks like the following, yours may look different.

Before

# SQLite version 3.x
#   gem install sqlite3-ruby (not necessary on OS X Leopard)
development:
  adapter: sqlite3
  database: db/development.sqlite3
  timeout: 5000

After

# SQLite version 3.x
#   gem install sqlite3-ruby (not necessary on OS X Leopard)
development:
     adapter: mysql
     database: FlexOnRailsAuthentication_dev
     username: root
     password: rootpassword
     host: localhost
     socket: /Applications/MAMP/tmp/mysql/mysql.sock

If you would like your db to hold more fields than what is auto generated by the plugin then edit the file in myBackend/db/migrate. I’ll add first_name and last_name

Return to terminal and run the following command to create the desired tables and columns in your db

rake db:migrate

Output should look like this

todd-rothes-macbook-pro:myBackend toddrothe$ rake db:migrate
(in /Users/toddrothe/Documents/Flex/Testing/FlexOnRailsAuthentication/myBackend)
== 20080818053624 CreateUsers: migrating ======================================
– create_table(“users”, {:force=>true})
-> 0.0048s
== 20080818053624 CreateUsers: migrated (0.0051s) =============================

check your db admin tool to ensure that you tables and columns were created properly

Start your server and see what you’ve got. The following url should display the form to create a new user

http://localhost:3000/users/new

Test this form and check that submission creates entries in your db.

Congrats! You have a working Rails app that creates a new user, storing their profile in your db. Next you will modify some of the files generated by the restful authentication plugin to allow the backend to better communicate with your Flex app.

In Flex Builder open myBackend/app/controllers/users_controller.rb and replace the existing ‘create‘ method with the following ‘create’ method. This will allow us to get xml back when submitting the form through your Flex app while retaining html functionality for your testing and peace of mind.

  def create
    cookies.delete :auth_token
    # protects against session fixation attacks, wreaks havoc with
    # request forgery protection.
    # uncomment at your own risk
    # reset_session
    @user = User.new(params[:user])
    @user.save!
    self.current_user = @user
    respond_to do |format|
      format.html do
        render :text => "Thanks for signing up!"
        flash[:notice] = "Thanks for signing up!"
      end
      format.xml { render :x ml => @user.to_xml }
    end
    rescue ActiveRecord::RecordInvalid
    respond_to do |format|
      format.html { render :action => 'new' }
      format.xml { render :text => "error" }
    end
  end

Now some clean up. cut line 2 and 3 from users_controller.rb and place them in myBackend/app/controllers/app_controller.rb after the class declaration to look like so

class ApplicationController < ActionController::Base
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem

While we are in app_controler.rb we also need to de-dasherize our response data so our ‘first_name’ property is not returned to our app as ‘first-name’. Dasherize is a default rails behavior. Add the followin code blocks to the top of the file.

module ActiveSupport #:nodoc:
    module CoreExtensions #:nodoc:
        module Hash #:nodoc:
            module Conversions
                # We force :dasherize to be false, since we never want
                # it true. Thanks very much to the reader on the
                # flexiblerails Google Group who suggested this better
                # approach.
                unless method_defined? :o ld_to_xml
                    alias_method :o ld_to_xml, :to_xml
                    def to_xml(options = {})
                        options.merge!(:dasherize => false)
                        old_to_xml(options)
                    end
                end
            end
        end
        module Array #:nodoc:
            module Conversions
            # We force :dasherize to be false, since we never want
            # it to be true.
                unless method_defined? :o ld_to_xml
                    alias_method :o ld_to_xml, :to_xml
                    def to_xml(options = {})
                        options.merge!(:dasherize => false)
                        old_to_xml(options)
                    end
                end
            end
        end
    end
end
module ActiveRecord #:nodoc:
    module Serialization
        # We force :dasherize to be false, since we never want it to
        # be true.
        unless method_defined? :o ld_to_xml
            alias_method :o ld_to_xml, :to_xml
            def to_xml(options = {})
                options.merge!(:dasherize => false)
                old_to_xml(options)
            end
        end
    end
end

Open myBackend/models/user.rb and append first_name and last_name to attr_accessible as follows.

  attr_accessible :login, :email, :password, :password_confirmation, :first_name, :last_name

Without this modification the xml response will contain something like this <first_name nil=”true”/>

To avoid a security sandbox violation we need to run/debug our app from our local server. Create an alias on your server and point it at the bin-debug dir of you project. Using MAMP you will open
/Applications/MAMP/conf/apache/httpd.conf

Search for Alias and add your own near /favicon.ico

Alias /fora "/Users/toddrothe/Documents/Flex/Testing/FlexOnRailsAuthentication/bin-debug/"

In Flex Builder run your empty project to generate run/debug properties which we will then modify.
Return to Flex Builder -> right click on your project -> properties -> Run / Debug Settings -> FlexOnRailsAuthentication -> Edit

In the ‘main’ tab uncheck ‘Use Defaults’ and replace the values in the input boxes with your functioning equivelant of server/alias/app.html
http://localhost:8888/fora/FlexOnRailsAuthentication.html

NOW THE FUN STUFF

Open FlexOnRailsAuthentication.mxml and build your service, your form, an XMLListCollection to hold the result of your service call and a datagrid to display the XMLListCollection.

Please see the zip file containing my sample project for complete files.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.ResultEvent;
            import mx.rpc.events.FaultEvent;
            private function handleUserCreateResult(event:ResultEvent):void {
                var result:Object = event.result;
                if (result == "error") {
                    trace("ERROR : "+event);
                } else {
                    trace("NICE! : \n"+svcUserCreate.lastResult.children());
                }
            }
            private function handleUserCreateFault(event:FaultEvent):void {
                var result:Object = event.fault;
                if (result == "error") {
                    trace("FAULT : "+event);
                }
            }
        ]]>
    </mx:Script>
    <mx:HTTPService    id="svcUserCreate" url="http://localhost:3000/users.xml"
        contentType="application/xml" resultFormat="e4x" method="POST"
        result="handleUserCreateResult(event)"
        fault="handleUserCreateFault(event)">
        <mx:request>
            <user>
                <login>{login.text}</login>
                <email>{email.text}</email>
                <first_name>{firstName.text}</first_name>
                <last_name>{lastName.text}</last_name>
                <password>{password.text}</password>
                <password_confirmation>{confirmPassword.text}</password_confirmation>
            </user>
        </mx:request>
    </mx:HTTPService>
    <mx:Form labelWidth="150">
        <mx:FormItem required="true" label="Username">
            <mx:TextInput id="login"/>
        </mx:FormItem>
        <mx:FormItem required="true" label="Email Address">
            <mx:TextInput id="email"/>
        </mx:FormItem>
        <mx:FormItem required="true" label="First Name">
            <mx:TextInput id="firstName"/>
        </mx:FormItem>
        <mx:FormItem required="true" label="Last Name">
            <mx:TextInput id="lastName"/>
        </mx:FormItem>
        <mx:FormItem required="true" label="Password">
            <mx:TextInput id="password"    displayAsPassword="true"/>
        </mx:FormItem>
        <mx:FormItem required="true" label="Confirm Password">
            <mx:TextInput id="confirmPassword" displayAsPassword="true"/>
        </mx:FormItem>
        <mx:FormItem>
            <mx:Button id="createAccountButton" label="Create Account" click="svcUserCreate.send()"/>
        </mx:FormItem>
    </mx:Form>
    <mx:XMLListCollection id="usersXML" source="{XMLList(svcUserCreate.lastResult)}"/>
    <mx:DataGrid id="tasksGrid" width="80%" height="20%" dataProvider="{usersXML}">
        <mx:columns>
            <mx:DataGridColumn headerText="First Name" width="300" dataField="first_name"/>
            <mx:DataGridColumn headerText="Last Name" width="150" dataField="last_name"/>
            <mx:DataGridColumn headerText="Login" width="150" dataField="login"/>
        </mx:columns>
    </mx:DataGrid>
</mx:Application>

That’s it!
Part 2 is on it’s way.

 

No Responses to “Flex On Rails User Authentication Quick Start Guide” (post new)

 

Leave a Reply

You must be logged in to post a comment.