我有一個使用flex和cakephp開發的Web應用程序。我的客戶需要使用Adobe Air製作該Web應用程序的桌面應用程序。 Flex向Air的轉換已成功完成。柔性應用程序flex和cakephp的通信是使用遠程控制器處理的。用於adobe air應用程序的cakephp用戶身份驗證
在空氣應用程序中,我有一個使用cakephp默認用戶身份驗證來驗證用戶的問題。任何人都可以幫助我找到解決方案嗎?
我有一個使用flex和cakephp開發的Web應用程序。我的客戶需要使用Adobe Air製作該Web應用程序的桌面應用程序。 Flex向Air的轉換已成功完成。柔性應用程序flex和cakephp的通信是使用遠程控制器處理的。用於adobe air應用程序的cakephp用戶身份驗證
在空氣應用程序中,我有一個使用cakephp默認用戶身份驗證來驗證用戶的問題。任何人都可以幫助我找到解決方案嗎?
我建議你通過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';
...
}
var loader:URLLoader = new URLLoader(); \t \t var req:URLRequest = new URLRequest(「http:// myurl/login」); \t \t var headerRequests:Array = new Array(1); \t \t req.method =「POST」; \t \t \t \t var headerRequests:Array = new Array(1); \t \t headerRequests [0] =新的URLRequestHeader(「email_address = email&password = pwd」); \t \t req.requestHeaders = headerRequests; \t \t裝載機。load(req);' 這是我爲發送請求所做的代碼。但似乎仍然認證失敗。它是否正確? – user1120633 2012-02-15 11:34:38
驗證是否在不使用FlexApp的情況下運行? 認證記錄在這裏:http://book.cakephp.org/2.0/en/core-libraries/components/authentication.html – 2012-02-15 11:40:18
是的。 Flex應用程序不涉及這裏。這純粹是一個AIR應用程序 – user1120633 2012-02-15 11:55:45
基本上,你要發送的驗證請求作爲一個Ajax請求。要做到這一點,你需要修改標題,通過cookie捕獲會話ID併發布它們以保持會話的活躍。它期望從Cake返回一個JSON對象。
我創建了幾個Flex類,爲Flex移動應用程序和CakePHP後端實現了這一點。它應該符合您的需求。
它有兩個文件,AutoValidationUrlRequest.as擴展了HeaderURLRequest.as文件。我並不積極,但可能會有一些變數需要改變,但總的來說,它的運行效果非常好,並且可能不會花費更多的修改來讓它在您的應用上運行。
要使用它,只需創建一個新的AutoValidationUrlRequest對象,並在headerUrlRequestComplete事件上添加事件偵聽器,然後運行AutoValidationUrlRequest.send(...)以POST。還有一個方便的方法稱爲convertToPostVars,以方便Cake友好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;
}
}
}
而且,利用此與我forked version of Jose Gonzalez's CakePHP ajax_controller plugin是非常方便的。它基本上接受任何Ajax請求並轉換所有視圖變量並將它們輸出到JSON對象中,而不是渲染視圖。否則,如果您沒有使用ajax請求,Cake將正常呈現視圖。祝你好運!
請更具體地解決您遇到的問題。你試過什麼了?例如,您是否發送POST請求並取回JSON? – swiecki 2012-02-15 05:02:45
由於cakephp有自己的方法來處理用戶登錄我想知道如何使用空氣處理它 – user1120633 2012-02-15 05:09:21