Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Authentication in jQuery Mobile and PhoneGap

I have a web application built with jQuery Mobile and PHP (CodeIgniter framework). Now I'm trying to make a PhoneGap version of it as well, to make it distributable as a standalone app. However, the PHP web app. version uses Ion Auth, a CodeIgniter plugin for authentication. So when you go to a page that requires authentication, the app redirects you to the authentication controller login method. And after authentication it redirects you back to the home page (the jQuery Mobile page in this case). This works fine in the web app., since the home page is opened by the home controller in the first place anyway.

But here's the crux: in the PhoneGap version, the "home" page needs to be the index.html file in PhoneGap. Apparently you can load another url on startup by adding a value in PhoneGap.plist, but that is not acceptable by apple for submitting to app store. And if I do a redirect in the authentication, I can't get back to the index.html file after authentication...

So how should one go about authentication in a PhoneGap/jQuery Mobile app?

UPDATE:

I have tried this according to one of the answers, but the app still tries to navigate to the account/login page (which doesn't exist), when I just want to login through the post and return a value from the method:

    $('#login_form').bind('submit', function () {
        event.preventDefault();
        //send a post request to your web-service
        $.post('http://localhost/app_xcode/account/login', $(this).serialize(), function (response) {
            //parse the response string into an object
            var response = response;
            //check if the authorization was successful or not
            if (response == true) {
                $.mobile.changePage('#toc', "slide");
            } else {
                alert('login failed');
                $.mobile.changePage('#toc', "slide");
            }
        });
    });

Here's the controller method:

function login()
    {
        //validate form input
        $this->form_validation->set_rules('identity', 'Identity', 'required');
        $this->form_validation->set_rules('password', 'Password', 'required');

        $base_url = $this->config->item('base_url');

        $mobile = $this->detect_mobile();
        if ($mobile === false && $base_url != 'http://localhost/app_xcode/') //Only restrict if not developing
            redirect('account/notAMobile');

        else if ($this->form_validation->run() == true) { //check to see if the user is logging in
            //check for "remember me"
            $remember = (bool)$this->input->post('remember');

            if ($this->ion_auth->login($this->input->post('identity'), $this->input->post('password'), $remember)) { //if the login is successful
                //redirect them back to the home page
                $this->session->set_flashdata('message', $this->ion_auth->messages());

                echo true;
                /*redirect($this->config->item('base_url'), 'refresh');*/
            }
            else
            { //if the login was un-successful
                //redirect them back to the login page
                $this->session->set_flashdata('message', $this->ion_auth->errors());
                /*redirect('account/login', 'refresh');*/ //use redirects instead of loading views for compatibility with MY_Controller libraries
            }
        }
        else
        { //the user is not logging in so display the login page
            //set the flash data error message if there is one
            $this->data['message'] = (validation_errors()) ? validation_errors()
                    : $this->session->flashdata('message');

            $this->data['identity'] = array('name' => 'identity',
                                            'id' => 'identity',
                                            'type' => 'text',
                                            'value' => $this->form_validation->set_value('identity'),
            );
            $this->data['password'] = array('name' => 'password',
                                            'id' => 'password',
                                            'type' => 'password',
            );

        }
    }

I think I have removed or commented out any redirects that were there. So I don't know why it tries to load the view still? Does it have something to do with jQuery Mobile trying to navigate there because I post to that url?

like image 548
Anders Avatar asked Nov 10 '11 12:11

Anders


3 Answers

The reason your form is still submitting and it's trying to change pages is because you have a syntax error in your submit handler Javascript. On line two, event is not defined so trying to call event.preventDefault() errors. Although the handler fails, the browser still submits the form using it's default action and method.

Either change your function signature to function(event) { or simply return false from the function. Returning false is equivalent to preventing default.

$('#login_form').bind('submit', function () {

    //send a post request to your web-service
    $.post('http://localhost/app_xcode/account/login', $(this).serialize(), function (response) {
        //check if the authorization was successful or not
        if (response == true) {
            $.mobile.changePage('#toc', "slide");
        } else {
            alert('login failed');
            $.mobile.changePage('#toc', "slide");
        }
    }, 'JSON');

    return false;
});
like image 87
Jeffrey D. Hoffman Avatar answered Oct 06 '22 20:10

Jeffrey D. Hoffman


You can make requests to your web-service (Ion Auth) from your app. with jQuery. Your login would look something like this:

//add event handler to the `submit` event for your login form
$('#login_form').bind('submit', function () {

    //send a post request to your web-service
    $.post('http://my-domain.com/my-auth/auth.php', $(this).serialize(), function (response) {

        //parse the response string into an object
        response = $.parseJSON(response);

        //check if the authorization was successful or not
        if (response.status === 'success') {
            //do login here
        } else {
            //do error here
        }
    });
});

$(this).serialize() will add the login form's data to the post request. This example assumes your web-service will return JSON.

like image 22
Jasper Avatar answered Oct 06 '22 19:10

Jasper


Have you looked at PhoneGap Plugin: ChildBrowser (iPhone, Android, other) and its locChanged method?

I have only coded apps that use OAuth (Twitter App) and OpenID (AppLaud App) for PhoneGap / Android, but the child browser plugin has what's needed for those. Sounds like Ion Auth may be similar: after auth driven by provider, return user to app seamlessly.

like image 40
Libby Avatar answered Oct 06 '22 20:10

Libby