phalcon php csrf token validation fails when working via ajax - php

Im am working with the phalcon Framework and i decided to work with the csrf function available. I followed all the steps needed as shown in documentation.
I receive the data, the token and its value and i run
$data = $this->request->getJsonRawBody();
print_r($data); //// proper data
if ($this->request->isPost()) {
if ($this->security->checkToken()) {
die('proper token');
}
else{die('NOT A proper token');}
}
And my post request is like this :
$scope.submit = function() {
$scope.formData.token = [$("#token").attr("name"), $("#token").val()];
$http.post(
'http://localhost/project/index/function',
JSON.stringify($scope.formData)
).success(function(data) { alert(data);
if (data.isValidToken) {
alert("Ok, you win!!!");
} else {
alert("Sorry, not valid CSRF !!!")
}
});
return false;
};
i check the session data, the tokens stored there while generating the form are different than the one's i print out when the ajax request is done .
Could someone point me what im doing wrong ?

Phalcon\Security::checkToken is use $_POST by default. If you need use ajax, pass tokenKey and tokenValue to Phalcon\Security::checkToken.
Check here
$data = $this->request->getJsonRawBody();
if ($this->request->isPost()) {
$tokenKey = $this->session->get('$PHALCON/CSRF/KEY$');
$tokenValue = $data->{$tokenKey};
if ($this->security->checkToken($tokenKey, $tokenValue)) {
die('proper token');
}
else{die('NOT A proper token');}
}

Related

CakePHP 4 Return data from controller to AJAX render issue

I am submitting data to a controller function via AJAX, doing what I need to do with the data, and trying to echo it back out to the ajax function.
The issue I am having, is the controller is dumping out the error message and trying to redirect me to the actual function. Obviously the function doesn't have a view, which results in a blank white screen with the response echoed out in the top left corner.
Here is the ajax:
$('#submit_new_split_promo').on('click',function(e){
e.preventDefault();
var id = $(this).data('id');
$('#d_overlay').show();
form = {};
$.each($('#promo-mail-split-add-'+id).serializeArray(),function(k,v){
form[this.name] = this.value;
});
$.ajax({
url:$('#promo-mail-split-add-'+id).attr('action'),
type:"POST",
dataType: "json",
data: form
}).done(function(result){
var res = JSON.parse(result);
if (res == 'Duplicate') {
$('#ms-promo').css('border','3px solid red');
$('#ms-promo').effect('shake');
$('#dynamodal-unique-title').text('That code has been used. Please enter a new Promo Code.');
$('#dynamodal-unique-title').text('That code has been used. Please enter a new Promo Code.').css('color','red').delay(2000).queue(function(next){
$('#dynamodal-unique-title').text('Create Mail Split Promo');
next();
});
return false;
}
$('#mail_split_promo_'+id).modal('toggle');
if (res == false) {
alert('Mail Split Promo did not save. Please try again.');
} else {
$('#add-promo-to-split-'+id).prop('disabled',true);
$('#promo-view-abled-'+id).hide();
$('#promo-view-disabled-'+id).show();
$('#promo-view-disabled-'+id).prop('disabled',false);
}
}).fail(function(){
}).always(function(){
$('#d_overlay').hide();
});
});
Here is the Controllers code
public function addpromo() {
$this->Authorization->skipAuthorization();
$this->request->allowMethod(['get','post']);
$this->autoRender = false;
$data = $this->request->getData();
$mail_split_id = $data['mail_split_id'];
$code = $data['code'];
$result = false;
$doesExist = $this->Promos->findByCode($code)->toArray();
if ($doesExist) {
$result = 'Duplicate';
}
if ($result !== 'Duplicate') {
$MailSplits = $this->getTableLocator()->get('MailSplits');
$mailSplit = $MailSplits->get($mail_split_id);
$entity = $this->Promos->newEmptyEntity();
foreach ($data as $key => $val) {
$entity->$key = $val;
}
$entity->record_count = $mailSplit->record_count;
$result = $this->Promos->save($entity);
if ($this->get_property($result,'id')) {
$promo_id = $result->id;
$MailSplits = $this->loadModel('MailSplits');
$mentity = $MailSplits->get($mail_split_id);
$mentity->promo_id = $promo_id;
$updated = $MailSplits->save($mentity);
if ($this->get_property($updated,'id')) {
$result = true;
} else {
$result = false;
}
$output = [];
exec(EXEC_PATH.'AddPromoToRecordSplits '.$promo_id,$output);
} else {
$result = false;
}
}
ob_flush();
echo json_encode($result);
exit(0);
}
The URL it is trying to redirect me to is: /promos/addpromo when I really just need to stay on the same page, which would be /mail-jobs/view
Response dumped to browser
A couple of things to note:
I have tried adding the function to the controllers policy, and actually authorizing an initialized entity. This has no effect and does not change the issue I am facing.
Something that is more frustrating, I have essentially the same code (ajax structure and controller structure) for other forms on the page, and they work just fine. The only difference seems to be any form that utilizes ajax that is on the page on render, works just fine. The ajax functions I am having an issue with, all seem to be from the forms rendered in Modals, which are different elements. Every form in a modal / element, gives me this issue and that's really the only pattern I have noticed.
Any help is greatly appreciated, I know it's an odd and vague issue.
Thank you!

Firebase Auth JS/PHP

I've been tasked to build a web interface for an Android app based on firebase.
I've got a handful of endpoints, that interact with the database (Cloud functions). To access those endpoints I need to authenticate an user with email and password[1], retrieve an accessToken[2] und authorize every request to the endpoints with an Authorization: Bearer {accessToken} header.
I use php and struggle to wrap my mind around how to manage authenticated user in my app.
TL;DR please see my final solution in php only. https://stackoverflow.com/a/52119600/814031
I transfer the accessToken via ajax in a php session, to sign the cURL requests to the endpoints.
Apparently there is no other way around than use the firebase JS auth (not as far as I understand[4]).
My question is: Is it enough to save the accessToken in a php session and compare it with every page load via an ajax POST request (see code below)?
What would be a more robust strategy to handle that in php?
Edit: A user pointed out that using classic php sessions with JWT tokens don't make much sense and I read up about that topic.
So regarding Firebase - is this something to consider?
https://firebase.google.com/docs/auth/admin/manage-cookies
Firebase Auth provides server-side session cookie management for traditional websites that rely on session cookies. This solution has several advantages over client-side short-lived ID tokens, which may require a redirect mechanism each time to update the session cookie on expiration:
Here is what I got:
1. Login Page
As described in the Firebase examples[3]
function initApp() {
firebase.auth().onAuthStateChanged(function (user) {
if (user) {
// User is signed in.
// obtain token, getIdToken(false) = no forced refresh
firebase.auth().currentUser.getIdToken(false).then(function (idToken) {
// Send token to your backend via HTTPS
$.ajax({
type: 'POST',
url: '/auth/check',
data: {'token': idToken},
complete: function(data){
// data = {'target' => '/redirect/to/route'}
if(getProperty(data, 'responseJSON.target', false)){
window.location.replace(getProperty(data, 'responseJSON.target'));
}
}
});
// ...
}).catch(function (error) {
console.log(error);
});
} else {
// User Signed out
$.ajax({
type: 'POST',
url: '/auth/logout',
complete: function(data){
// data = {'target' => '/redirect/to/route'}
if(getProperty(data, 'responseJSON.target', false)){
// don't redirect to itself
// logout => /
if(window.location.pathname != getProperty(data, 'responseJSON.target', false)){
window.location.replace(getProperty(data, 'responseJSON.target'));
}
}
}
});
// User is signed out.
}
});
}
window.onload = function () {
initApp();
};
2. a php controller to handle the auth requests
public function auth($action)
{
switch($action) {
// auth/logout
case 'logout':
unset($_SESSION);
// some http status header and mime type header
echo json_encode(['target' => '/']); // / => index page
break;
case 'check':
// login.
if(! empty($_POST['token']) && empty($_SESSION['token'])){
// What if I send some bogus data here? The call to the Endpoint later would fail anyway
// But should it get so far?
$_SESSION['token'] = $_POST['token'];
// send a redirect target back to the JS
echo json_encode(['target' => '/dashboard']);
break;
}
if($_POST['token'] == $_SESSION['token']){
// do nothing;
break;
}
break;
}
}
3. the Main controller
// pseudo code
class App
{
public function __construct()
{
if($_SESSION['token']){
$client = new \GuzzleHttp\Client();
// $user now holds all custom access rights within the app.
$this->user = $client->request(
'GET',
'https://us-centralx-xyz.cloudfunctions.net/user_endpoint',
['headers' =>
[
'Authorization' => "Bearer {$_SESSION['token']}"
]
]
)->getBody()->getContents();
}else{
$this->user = null;
}
}
public function dashboard(){
if($this->user){
var_dump($this->user);
}else{
unset($_SESSION);
// redirect to '/'
}
}
}
Note: I'm aware of this sdk https://github.com/kreait/firebase-php and I read a lot in the issues there and in posts here on SO, but I got confused, since there is talk about full admin rights etc. and I really only interact with the endpoints that build upon firebase (plus firebase auth and firestore). And I'm still on php 5.6 :-/
Thanks for your time!
[1]: https://firebase.google.com/docs/auth/web/password-auth
[2]: https://firebase.google.com/docs/reference/js/firebase.User#getIdToken
[3]: https://github.com/firebase/quickstart-js/blob/master/auth/email-password.html
[4]: https://github.com/kreait/firebase-php/issues/159#issuecomment-360225655
I have to admit, the complexity of the firebase docs and examples and different services, got me so confused, that I thought, authentication for the web is only possible via JavaScript. That was wrong. At least for my case, where I just login with email and password to retrieve a Json Web Token (JWT), to sign all calls to the Firebase cloud functions. Instead of juggling with weird Ajax requests or set the token cookie via JavaScript, I just needed to call the Firebase Auth REST API
Here is a minimal case using the Fatfreeframework:
Login form
<form action="/auth" method="post">
<input name="email">
<input name="password">
<input type="submit">
</form>
Route
$f3->route('POST /auth', 'App->auth');
Controller
class App
{
function auth()
{
$email = $this->f3->get('POST.email');
$password = $this->f3->get('POST.password');
$apiKey = 'API_KEY'; // see https://firebase.google.com/docs/web/setup
$auth = new Auth($apiKey);
$result = $auth->login($email,$password);
if($result['success']){
$this->f3->set('COOKIE.token',$result['idToken']);
$this->f3->reroute('/dashboard');
}else{
$this->f3->clear('COOKIE.token');
$this->f3->reroute('/');
}
}
}
Class
<?php
use GuzzleHttp\Client;
class Auth
{
protected $apiKey;
public function __construct($apiKey){
$this->apiKey = $apiKey;
}
public function login($email,$password)
{
$client = new Client();
// Create a POST request using google api
$key = $this->apiKey;
$responsee = $client->request(
'POST',
'https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword?key=' . $key,
[
'headers' => [
'content-type' => 'application/json',
'Accept' => 'application/json'
],
'body' => json_encode([
'email' => $email,
'password' => $password,
'returnSecureToken' => true
]),
'exceptions' => false
]
);
$body = $responsee->getBody();
$js = json_decode($body);
if (isset($js->error)) {
return [
'success' => false,
'message' => $js->error->message
];
} else {
return [
'success' => true,
'localId' => $js->localId,
'idToken' => $js->idToken,
'email' => $js->email,
'refreshToken' => $js->refreshToken,
'expiresIn' => $js->expiresIn,
];
}
}
}
Credits
Sounds like #Chad K is getting you on the right track (cookies and ajax - breakfast of champions... :), though I thought to share my code from my working system (with some 'privacy' things, of course!)
Look for /**** type comments for things you need to set up yourself (you may want to do some other firebase things differently as well - see the docs...)
LOGIN.php page (I found it simpler overall to keep this separate - see notes to learn why....)
<script>
/**** I picked this up somewhere off SO - kudos to them - I use it a lot!.... :) */
function setCookie(name, value, days = 7, path = '/') {
var expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expires + '; path=' + path;
}
function getCookie(c_name) {
if (document.cookie.length > 0) {
c_start = document.cookie.indexOf(c_name + "=");
if (c_start !== -1) {
c_start = c_start + c_name.length + 1;
c_end = document.cookie.indexOf(";", c_start);
if (c_end === -1) {
c_end = document.cookie.length;
}
return unescape(document.cookie.substring(c_start, c_end));
}
}
return "";
}
</script>
<script>
var config = {
apiKey: "your_key",
authDomain: "myapp.firebaseapp.com",
databaseURL: "https://myapp.firebaseio.com",
projectId: "myapp",
storageBucket: "myapp.appspot.com",
messagingSenderId: "the_number"
};
firebase.initializeApp(config);
</script>
<script src="https://cdn.firebase.com/libs/firebaseui/2.7.0/firebaseui.js"></script>
<link type="text/css" rel="stylesheet" href="https://cdn.firebase.com/libs/firebaseui/2.7.0/firebaseui.css"/>
<script type="text/javascript">
/**** set this url to the 'logged in' page (mine goes to a dashboard) */
var url = 'https://my.app/index.php#dashboard';
/**** by doing this signOut first, then it is simple to send any 'logout' request in the app to 'login.php' - one page does it.... :) */
firebase.auth().signOut().then(function () {
}).catch(function (error) {
console.log(error);
});
var signInFlow = 'popup';
if (('standalone' in window.navigator)
&& window.navigator.standalone) {
signInFlow = 'redirect';
}
var uiConfig = {
callbacks: {
signInSuccessWithAuthResult: function (authResult, redirectUrl) {
/**** here you can see the logged in user */
var firebaseUser = authResult.user;
var credential = authResult.credential;
var isNewUser = authResult.additionalUserInfo.isNewUser;
var providerId = authResult.additionalUserInfo.providerId;
var operationType = authResult.operationType;
/**** I like to force emailVerified...... */
if (firebaseUser.emailVerified !== true) {
firebase.auth().currentUser.sendEmailVerification().then(function () {
/**** if using this, you can set up your own usermgmt.php page for the user verifications (see firebase docs) */
window.location.replace("https://my.app/usermgmt.php?mode=checkEmail");
}).catch(function (error) {
console.log("an error has occurred in sending verification email " + error)
});
}
else {
var accessToken = firebaseUser.qa;
/**** set the Cookie (yes, I found this best, too) */
setCookie('firebaseRegistrationID', accessToken, 1);
/**** set up the AJAX call to PHP (where you will store this data for later lookup/processing....) - I use "function=....." and "return=....." to have options for all functions and what to select for the return so that ajax.php can be called for 'anything' (you can just call a special page if you like instead of this - if you use this idea, be sure to secure the ajax.php 'function' call to protect from non-authorized use!) */
var elements = {
function: "set_user_data",
user: JSON.stringify(firebaseUser),
return: 'page',
accessToken: accessToken
};
$.ajaxSetup({cache: false});
$.post("data/ajax.php", elements, function (data) {
/**** this calls ajax and gets the 'page' to set (this is from a feature where I store the current page the user is on, then when they log in again here, we go back to the same page - no need for cookies, etc. - only the login cookie is needed (and available for 'prying eyes' to see!) */
url = 'index.php#' + data;
var form = $('<form method="post" action="' + url + '"></form>');
$('body').append(form);
form.submit();
});
}
return false;
},
signInFailure: function (error) {
console.log("error - signInFailure", error);
return handleUIError(error);
},
uiShown: function () {
var loader = document.getElementById('loader');
if (loader) {
loader.style.display = 'none';
}
}
},
credentialHelper: firebaseui.auth.CredentialHelper.ACCOUNT_CHOOSER_COM,
queryParameterForWidgetMode: 'mode',
queryParameterForSignInSuccessUrl: 'signInSuccessUrl',
signInFlow: signInFlow,
signInSuccessUrl: url,
signInOptions: [
firebase.auth.GoogleAuthProvider.PROVIDER_ID,
// firebase.auth.FacebookAuthProvider.PROVIDER_ID,
// firebase.auth.TwitterAuthProvider.PROVIDER_ID,
{
provider: firebase.auth.EmailAuthProvider.PROVIDER_ID,
requireDisplayName: true,
customParameters: {
prompt: 'select_account'
}
}
/* {
provider: firebase.auth.PhoneAuthProvider.PROVIDER_ID,
// Invisible reCAPTCHA with image challenge and bottom left badge.
recaptchaParameters: {
type: 'image',
size: 'invisible',
badge: 'bottomleft'
}
}
*/
],
tosUrl: 'https://my.app/login.php'
};
var ui = new firebaseui.auth.AuthUI(firebase.auth());
(function () {
ui.start('#firebaseui-auth-container', uiConfig);
})();
</script>
Now, on every page you want the user to see (in my case, it all goes through index.php#something - which makes it easier.... :)
<script src="https://www.gstatic.com/firebasejs/4.12.0/firebase.js"></script>
<script>
// Initialize Firebase - from https://github.com/firebase/firebaseui-web
var firebaseUser;
var config = {
apiKey: "your_key",
authDomain: "yourapp.firebaseapp.com",
databaseURL: "https://yourapp.firebaseio.com",
projectId: "yourapp",
storageBucket: "yourapp.appspot.com",
messagingSenderId: "the_number"
};
firebase.initializeApp(config);
initFBApp = function () {
firebase.auth().onAuthStateChanged(function (firebaseuser) {
if (firebaseuser) {
/**** here, I have another ajax call that sets up some select boxes, etc. (I chose to call it here, you can call it anywhere...) */
haveFBuser();
firebaseUser = firebaseuser;
// User is signed in.
var displayName = firebaseuser.displayName;
var email = firebaseuser.email;
var emailVerified = firebaseuser.emailVerified;
var photoURL = firebaseuser.photoURL;
if (firebaseuser.photoURL.length) {
/**** set the profile picture (presuming you are showing it....) */
$(".profilepic").prop('src', firebaseuser.photoURL);
}
var phoneNumber = firebaseuser.phoneNumber;
var uid = firebaseuser.uid;
var providerData = firebaseuser.providerData;
var string = "";
firebaseuser.getIdToken().then(function (accessToken) {
// document.getElementById('sign-in-status').textContent = 'Signed in';
// document.getElementById('sign-in').textContent = 'Sign out';
/**** set up another ajax call.... - to store things (yes, again.... - though this time it may be due to firebase changing the token, so we need it twice...) */
string = JSON.stringify({
displayName: displayName,
email: email,
emailVerified: emailVerified,
phoneNumber: phoneNumber,
photoURL: photoURL,
uid: uid,
accessToken: accessToken,
providerData: providerData
});
if (accessToken !== '<?php echo $_COOKIE['firebaseRegistrationID']?>') {
console.log("RESETTING COOKIE with new accessToken ");
setCookie('firebaseRegistrationID', accessToken, 1);
var elements = 'function=set_user_data&user=' + string;
$.ajaxSetup({cache: false});
$.post("data/ajax.php", elements, function (data) {
<?php
/**** leave this out for now and see if anything weird happens - should be OK but you might want to use it (refreshes the page when firebase changes things..... I found it not very user friendly as they reset at 'odd' times....)
/*
// var url = 'index.php#<?php echo(!empty($user->userNextPage) ? $user->userNextPage : 'dashboard'); ?>';
// var form = $('<form action="' + url + '" method="post">' + '</form>');
// $('body').append(form);
// console.log('TODO - leave this form.submit(); out for now and see if anything weird happens - should be OK');
// form.submit();
*/
?>
});
}
});
} else {
console.log("firebase user CHANGED");
document.location.href = "../login.php";
}
}, function (error) {
console.log(error);
}
);
};
window.addEventListener('load', function () {
initFBApp();
});
</script>
Hope this helps. It is from my working system, which includes some extra features I've put in there along the way, but mostly it is directly from firebase so you should be able to follow along well enough.
Seems a much simpler route to take than your original one.
You really aren't supposed to use sessions in PHP when using tokens. Tokens should be sent in the header on every request (or a cookie works too).
Tokens work like this:
1. You sign in, the server mints a token with some information encoded
2. You send that token back on every request
Based on the information encoded in the token, the server can get information about the user. Typically a User ID of some sort is encoded in it. The server knows it's a valid token because of the way it's encoded.
Send the token on every request you need to make, then in PHP you can just pass that token to the other API

Having trouble setting cookie via AJAX login with Yii2

I'm using Yii2 and I have setup a login process which works fine (cookies as well) via the standard login page which is not AJAX.
I have built a dropdown login field which works fine at logging them in, however it doesn't seem to set the cookie as the user doesn't stay logged in and there is no bookie created.
I figured that this was because of AJAX and the cookie wasn't being created on the users system, but upon further reading it seems it should work.
I have verified that the cookie value is being set correctly, the only issue is the cookie doesn't seem to being created.
My login code:
JS:
function doLogin() {
// Set file to prepare our data
var loadUrl = "../../user/login/";
// Set parameters
var dataObject = $('#login_form').serialize();
// Set status element holder
var status_el = $('#login_status');
// Make sure status element is hidden
status_el.hide();
// Run request
getAjaxData(loadUrl, dataObject, 'POST', 'json')
.done(function(response) {
if (response.result == 'success') {
//.......
} else {
//.......
}
})
.fail(function() {
//.......
});
// End
}
function getAjaxData(loadUrl, dataObject, action, type) {
if ($('meta[name="csrf-token"]').length) {
// Add our CSRF token to our data object
dataObject._csrf = $('meta[name="csrf-token"]').attr('content');
}
return jQuery.ajax({
type: action,
url: loadUrl,
data: dataObject,
dataType: type
});
}
Controller:
public function actionLogin() {
// Check if they already logged in
if (!Yii::$app->user->isGuest and !Yii::$app->request->isAjax) {
return $this->redirect('/');
}
if (Yii::$app->request->isAjax) {
// Set our data holder
$response = ['output' => '', 'result' => 'error'];
}
// Let's send the POST data to the model and see if their login was valid
if (Yii::$app->request->isAjax and $this->user->validate() and $this->user->login()) {
$response['result'] = 'success';
} elseif (!Yii::$app->request->isAjax and Yii::$app->request->isPost and $this->user->validate() and $this->user->login()) {
//.......
} else {
//.......
}
if (Yii::$app->request->isAjax) {
echo Json::encode($response);
}
}
Model:
public function login() {
// Set cookie expire time
$cookie_expire = 3600 * 24 * Yii::$app->params['settings']['cookie_expire'];
return Yii::$app->user->login($this->getUser(), ($this->remember_me ? $cookie_expire : 0));
}
As I suspected (see my earlier comment) response might not be correctly generated in case of simply echoing the data. Or maybe Content-Type header matters. If someone can confirm this it will be great.
Anyway, I'm glad it works now (data needs to be returned).
And you can use Response handy format as well.
public function actionLogin() {
// ...
if (Yii::$app->request->isAjax) {
Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
return $response;
}
}

JSON and PHP issues

I'm new to JSON and AJAX, and as such have searched for solutions and experimented for a few days before resorting to asking here.
I am using AJAX to process a PHP page on submit. It is saving the information fine, but I also need the PHP page to pass back the inserted ID. Here is what I have so far.
In the success:
success: function(){
$('#popup_name img').remove();
$('#popup_name').html('Saved');
$('#fade , .popup_block').delay(2000).fadeOut(function() {
$('#fade, a.close').remove(); //fade them both out
$.getJSON(pathName, function(json){
alert('You are here');
alert("Json ID: " + json.id);
});
});
}
Then, the PHP script calls this method to insert the info and return the inserted id:
public static function doInsertQuery($sparamQuery="",$bparamAutoIncrement=true,$sparamDb="",$sparamTable=""){
//do the insert
$iReturn = 0;
$result = DbUtil::doQuery($sparamQuery);
if(!$result){
$iReturn = 0;
}
elseif(!$bparamAutoIncrement){
$iReturn = DbUtil::getInsertedId();
}
else{
$iReturn = DbUtil::getInsertedId();
}
//log the insert action
//if not a client logged in- cannot log to client db
if(Session::get_CurrentClientId() > 0){
if($sparamTable != LogLogin::table_LOGLOGINS()){
$oLog = new LogDbRequest();
$oLog->set_Type(LogDbRequest::enumTypeInsert);
$oLog->set_Request($sparamQuery);
$oLog->set_RowId($iReturn);
$oLog->set_TableName($sparamTable);
$oLog->set_Before("NULL");
$oLog->set_After(serialize(DbUtil::getRowCurrentValue($sparamDb,$sparamTable)));
$oLog->insertorupdate_LogDbRequest();
}
}
echo json_encode($iReturn);
return $iReturn;
}
I hope this makes sense. I'm at a complete loss here. Any help at all would be greatly appreciated!
~Mike~
It's simple really. The success function accepts an argument corresponding to the response from the server.
Client side:
$.ajax({
'url':'/path/to/script.php',
'dataType':'json',
'success':function(response){ //note the response argument
alert(response.id); //will alert the id
}
});
Server side:
<?php
//...previous stuff here...
$response = array('id' => $id); //where $id is the id to return to the client
header('Content-type: application/json'); //Set the right content-type header
echo json_encode($response); //Output array as JSON
?>

Modify the server side functions using jquery

I am developing one website using cakephp and jquery technologies.
Server-side there are some functions which handles SQL queries.
As per requirement I want to modify server side functions on client side using jQuery AJAX call.
E.g. : Below is the function on server side to modify users information.
function modifyUser(username,userid) {
//update query statements
}
Then jquery AJAX call will be like this:
$.ajax({
url: 'users/modiyUser',
success: function() {
alert("Updation done") or any statements.
}
});
and I want to modify above i.e. server side function depending upon client input criteria.
$.ajax({
function users/modiyUser(username,userid) {
// I will write here any other statements which gives me some other output.
}
});
Above AJAX call syntax may not present, but i think you all understood what I am trying to do I simply wants to modify/override server side functions on client side.
Please let me know is there any way to resolve above mentioned requirement.
Thanks in advance
You cannot call a PHP functions from the client directly. You can only make an HTTP request to a URI.
The URI determines the PHP script run. Input can be taken via $_GET, $_POST, and $_COOKIE (among others, but those are the main ones).
You can either write separate scripts for each function or determine what to do based on the user input.
You could have a server-side function in a separate PHP file to do this, and make an AJAX call call into that function first to perform the modification. But client-side changes to server-side code are just not possible.
I can't actually imagine why you would want to do this, though.
why override a function???
can i suggest this?
in PHP
try {
// functions here....
function modifyUser($username,$userid) {
//update query statements
if(!is_string($username)) throw new Exception("argument to " . __METHOD__ . " must be a string");
if(!is_string($userid)) throw new Exception("argument to " . __METHOD__ . " must be a string");
// do some modification codes....
}
function delete($userid){
// do stuff blah blahh...
}
// $_POST or $_GET etc. here
if(isset($_GET["modify"])){ // I make use of get for simplicity sake...
$username = $_GET['username'];
$userid = $_GET['userid'];
modifyUser($username,$userid);
$ret = array();
$ret["error"] = false;
$ret["msg"] = "$username has been modified";
echo json_encode($ret);
} else if(isset($_GET["delete"])) {
$userid = $_GET['userid'];
delete($userid);
$ret = array();
$ret["error"] = false;
$ret["msg"] = "$username has been deleted";
echo json_encode($ret);
}else {
// the client asked for something we don't support
throw new Exception("not supported operation");
}
}
catch(Exception $e){
// something bad happened
$ret = array();
$ret["error"] = true;
$ret["msg"] = $e->getMessage();
echo json_encode($ret);
}
in jQuery ajax
$.ajax({
url: 'ajax.php',
data : { modify : true, // sample for modify... can also be delete : true,
username : $('#username').val(),
userid : $('#userid').val() },
type: 'GET',
dataType: 'json',
timeout: 1000,
error: function(){
alert('error in connection');
},
success: function(data){
if(data.error)
alert('Something went wrong: ' + data.msg);
else {
alert('Success: ' + data.msg);
}
}
});

Categories