Аутентификация пользователя CakePHP для приложения Adobe Air - PullRequest
0 голосов
/ 15 февраля 2012

У меня есть веб-приложение, разработанное с использованием flex и cakephp. Мой клиент должен сделать настольное приложение из этого веб-приложения, используя Adobe Air Преобразование гибкого трубопровода в воздух выполнено успешно. В приложении flex взаимодействие flex и cakephp осуществляется с помощью пульта дистанционного управления.

В эфирном приложении у меня проблема с аутентификацией пользователя по умолчанию с помощью cakephp. Может кто-нибудь помочь мне найти решение для этого?

Ответы [ 2 ]

0 голосов
/ 20 февраля 2012

По сути, вы хотите отправить запрос проверки в качестве запроса ajax. Для этого вам нужно изменить заголовки, перехватить идентификаторы сеансов с помощью файлов cookie и опубликовать их, чтобы сохранить сеанс в действии. Он ожидает JSON-объект, возвращенный из Cake.

Я создал пару классов Flex, которые достигают именно этого для мобильного приложения Flex и серверной части CakePHP. Он должен работать так же для ваших нужд.

Он находится в двух файлах, AutoValidationUrlRequest.as расширяет файл HeaderURLRequest.as. Я не уверен, но может быть несколько переменных, которые нужно изменить, но в целом это работает очень хорошо и, вероятно, не потребует больше пары изменений, чтобы заставить его работать в вашем приложении.

Чтобы использовать его, просто создайте новый объект AutoValidationUrlRequest и добавьте прослушиватель событий в событие headerUrlRequestComplete, а затем запустите AutoValidationUrlRequest.send (...) для POST. есть также удобный метод convertToPostVars для простых переменных Cake Friendly Post.

AutoValidationUrlRequest.as:

package libs 
{

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.HTTPStatusEvent;

import models.LocalDeviceData;
import models.Model;

import mx.collections.ArrayCollection;
import mx.core.FlexGlobals;
import mx.utils.ObjectUtil;

[Event("LoginFailed")]
[Event("MobileUserDoesNotExist")]

public class AutoValidationURLRequest extends HeaderURLRequest
{       
    public static const LOGIN_FAILED:String = "LoginFailed";
    public static const MOBILE_USER_DOES_NOT_EXIST:String = "MobileUserDoesNotExist";
    /** 
     * will automatically be set by this class, if not set will login
     */ 
    public var requestHeaders:Object = new Object();
    private var _cookie:Object;

    /** 
     * should be an object with name of the cookie variables parsed in as key/value pairs
     */
    protected function set cookie(ck:Object):void{
        _cookie = ck;
    }

    protected function get cookie():Object{
        return _cookie;
    }

    public function AutoValidationURLRequest(){

    };

    public function send(url:String, postData:Object, generateUrlVars:Boolean = true):void{
        if(generateUrlVars){
            postData = convertToPostVars(postData);
        }
        sendRequest("http://yourwebsite.com"+url, postData, requestHeaders);
    }

    override protected function parseHeaders(e:HTTPStatusEvent):void{
        super.parseHeaders(e);
        if('Set-Cookie' in headers){
            requestHeaders['Cookie'] = parseCookie(headers['Set-Cookie']);
            //requestHeaders['User-Agent'] = headers['User-Agent'];
        }
    }


    /**
     *  returns the cookie key/val string for send requests back to the server 
     */
    protected function parseCookie(cookieString:String):String{
        var cookieObj:Object = new Object();
        var cookieBits:Array = cookieString.split("; ");
        return cookieBits[0]; 

        /*
        for each(var ck:String in cookieBits){
            var cb:Array = ck.split("=");
            cookieObj[cb[0]] = cb[1];
        }
        return cookieObj;
        */
    }

}
}

HeaderURLRequest.as:

package libs 
{

import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.HTTPStatusEvent;
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.net.URLRequestHeader;
import flash.net.URLRequestMethod;
import flash.net.URLVariables;

import mx.core.FlexGlobals;
import mx.rpc.events.ResultEvent;
import mx.utils.ObjectUtil;


[Event("headerUrlRequestComplete")]

public class HeaderURLRequest extends EventDispatcher
{
    public static const HEADERURLREQUEST_COMPLETE:String = "headerUrlRequestComplete";

    public var headers:Array = [];
    public var data:Object = new Object();
    public var variables:Object = new Object();
    public var invalidFields:Object = new Object();
    public var errorMsg:String = "";


    /**
     * the headers array must contain an object with a 'name' key and a 'value' key eg: cookie: <cookieStr>
     */
    public function HeaderURLRequest():void{
    }

    public function sendRequest(url:String, postData:Object = null, requestHeaders:Object = null):void{
        var urlLoader:URLLoader = new URLLoader()
        var urlRequest : URLRequest = new URLRequest(url);

        //make it an ajax request
        urlRequest.requestHeaders.push(new URLRequestHeader('X-Requested-With', 'XMLHttpRequest'));

        for(var header:* in requestHeaders){
            var authHeader:URLRequestHeader = new URLRequestHeader(header as String, requestHeaders[header]); 
            urlRequest.requestHeaders.push(authHeader)
        }
        var urlVariables:URLVariables = new URLVariables();
        for (var vars:* in postData){
            urlVariables[vars] = postData[vars];
        }

        urlRequest.method = URLRequestMethod.POST
        urlRequest.data = urlVariables;
        urlLoader.addEventListener(Event.COMPLETE, getData);
        urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, parseHeaders);
        urlLoader.load(urlRequest);

    }

    public function convertToPostVars(postData:Object, prependKeyName:String = ""):Object{
        var params:Object = {};
        if(prependKeyName == ""){
            params['_method'] = 'POST';
        }
        for (var item:* in postData){
            var objtype:Object = ObjectUtil.getClassInfo(postData[item]);
            if(objtype.name == "Object"){
                var modelKeyName:String = prependKeyName+"["+item+"]";
                var subParams:Object = convertToPostVars(postData[item],modelKeyName);
                params = merge(params, subParams);
            }else{
                params["data"+prependKeyName+"["+item+"]"] = postData[item];
            }
        }
        return params;
    }

    public function flashErrorMsg():String{
        var err:String = errorMsg;
        errorMsg = "";
        return err;
    }

    protected function parseHeaders(e:HTTPStatusEvent):void{
        var i:Number=0;
        headers = [];
        for each(var header:URLRequestHeader in e.responseHeaders){
            headers[header.name] = header.value;
        i++;
        } 
    }

    protected function getData(e:Event):void{
        //trace('data: ');
        if(e.currentTarget.data == ''){
            e.currentTarget.data = '{}';
        }
        data = JSON.parse(e.currentTarget.data);

        //trace(ObjectUtil.toString(data));
        if(data.hasOwnProperty('variables')){
            variables = data.variables;
            if (variables != null){
                if(variables.hasOwnProperty('invalidFields')){
                    invalidFields = variables.invalidFields;
                    for (var error:String in invalidFields){
                        errorMsg += invalidFields[error] + "\n\n";
                    }
                }
            }else{
                //no variable data found!!
            }
        }
        dispatchEvent(new Event(HEADERURLREQUEST_COMPLETE));
    }   

    public function isEmpty(obj:Object){
        var isEmpty:Boolean = true;
        for (var n in obj) { isEmpty = false; break; }
        return isEmpty;
    }

    public function merge( obj0:Object, obj1:Object ):Object
    {
        var obj:Object = { };
        for( var p:String in obj0 )
        {
            obj[ p ] = ( obj1[ p ] != null ) ? obj1[ p ] : obj0[ p ];
            //trace( p, ' : obj0', obj0[ p ], 'obj1', obj1[ p ], '-> new value = ', obj[ p ] );
        }
        for (var p1:String in obj1){
            if(!obj.hasOwnProperty(p1)){
                obj[ p1 ] =  obj1[ p1 ] ;
            }
        }
        return obj;
    }
}
}

Кроме того, использование этого с моей разветвленной версией плагина CakePHP ajax_controller Хосе Гонсалеса действительно удобно. Он в основном принимает любой Ajax-запрос и преобразует все переменные представления и выводит их в объект JSON, а не визуализированное представление. В противном случае, если вы не используете ajax-запрос, Cake отобразит представления в обычном режиме. Удачи!

0 голосов
/ 15 февраля 2012

Я предлагаю вам отправить свои учетные данные через POST на ваш сервер CakePHP.

Функция входа в ваш UsersController будет выглядеть примерно так:

public function login() {
    if ($this->Auth->login()) {
    $this->serviceResponse(Status::SUCCESS);
} else {
    $this->serviceResponse(Status::AUTH_FAILED);
    }
}

// this is just an example out of my appcontroller to send json responses
public function serviceResponse($code, $data = array()) {
    $response = compact('code', 'data');
    $this->response->body(json_encode($response));
    $this->response->send();
    $this->shutdownProcess();
    exit;
}

// I also defined a class for return statuses
class Status {
    const SUCCESS = 'success';
    const ERROR = 'error';
    ...
}
...