I have REST api on backend created with php (slim php micro framework). So code is:
INDEX.php
$app->post('/coords', 'authenticate', function() use ($app) {
$response = array();
//$jsonData = $app->request->post('podaci');
$jsonData = #file_get_contents('php://input');
$aData = json_decode($jsonData);
$latitude = $aData->location->latitude;
$longitude = $aData->location->longitude;
$podaci = $latitude.' ddd '.$longitude;
global $user_id;
$db = new DbHandler();
// creating new task
$coords_id = $db->createCoords($user_id, $podaci);
if ($coords_id != NULL) {
$response["error"] = false;
$response["message"] = "Coords insert successfully";
echoRespnse(201, $response);
} else {
$response["error"] = true;
$response["message"] = "Coords not inserted";
echoRespnse(200, $response);
}
});
I also have DBhandler file , code (function createCoords):
public function createCoords($user_id, $podaci) {
$stmt = $this->conn->prepare("INSERT INTO coords(podaci) VALUES(?)");
$stmt->bind_param("s", $podaci);
$result = $stmt->execute();
$stmt->close();
}
I try this REST api with sample data with ajax request and work well, but now I need to POST data from phonegap app to server and I write:
// BackgroundGeoLocation is highly configurable.
bgGeo.configure(callbackFn, failureFn, {
url: 'http://agroagro.com/agroMobile/v1/coords', // <-- Android ONLY: your server url to send locations to
params: {
Auth: 'df6017abde2d2re560896b63a0ee1039', // <-- Android ONLY: HTTP POST params sent to your server when persisting locations.
foo: 'bar' // <-- Android ONLY: HTTP POST params sent to your server when persisting locations.
},
desiredAccuracy: 0,
stationaryRadius: 50,
distanceFilter: 50,
notificationTitle: 'Background tracking', // <-- android only, customize the title of the notification
notificationText: 'ENABLED', // <-- android only, customize the text of the notification
activityType: 'AutomotiveNavigation',
debug: true, // <-- enable this hear sounds for background-geolocation life-cycle.
stopOnTerminate: false // <-- enable this to clear background location settings when the app terminates
});
I read here how to make php file to get INPUT data: https://github.com/christocracy/cordova-plugin-background-geolocation/issues/79
as you can see from my index.php code I write everything fine but what can be problem? This just dont work when I test on my android phone.
I do not why you are using 'php://input'); for getting json data.
Its simple. use the following to grab the json data sent from your phone.
$request = $app->request();
$body = $request->getBody();
$input = json_decode($body);
To know more how to handle json data using slim you may try the following website.
http://www.ibm.com/developerworks/library/x-slim-rest/
Related
Hi I am using cakephp as backend and want to generate a custom token for my website which will be used on my client side.
Below is my code to generate a custom code
$activatedOfferwall = $session->read('ActiveOfferwall'); // 0209341c-da14-46b9-b3c9-8410472e13d2
$factory = (new Factory)->withServiceAccount(\App\Model\Constants\FirebaseConstants::JSON_FILE)->withDatabaseUri(\App\Model\Constants\FirebaseConstants::DEFAULT_URL);
$auth = $factory->createAuth();
$customToken = $auth->createCustomToken($activatedOfferwall['UserHash']);
Log::debug(json_encode($customToken));
and the fire base rules are
but this always returns an empty json. What am I missing here?
For someone who is looking, I found the solution. Rules had to be
$generator = CustomTokenGenerator::withClientEmailAndPrivateKey(
$email,
$privateKey
);
$token = $generator->createCustomToken('anthony#gmail.com');
and then send the token on the client side
firebase.auth().signInWithCustomToken(usertoken)
.then((userCredential) => {
// Signed in
var user = userCredential.user;
firebase.auth().currentUser.getIdToken( /* forceRefresh */ true).then(function(idToken) {
console.log(idToken)
}).catch(function(error) {
// Handle error
});
})
.catch((error) => {
var errorCode = error.code;
var errorMessage = error.message;
console.log(error);
// ...
});
it's not only about the rules. if you are using the package kreait/laravel-firebase (https://firebase-php.readthedocs.io/en/stable/overview.html)
you will have to get the token with it's own method like this:
$firebaseCustomToken = $firebaseAuth->createCustomToken($user->id);
$CustomToken = $firebaseCustomToken->toString(); // like this will return the customToken
hope this helps someone
Reference of the git change here: https://github.com/kreait/firebase-php/commit/8b45c07d922364ba9298fa07cbe7ea676c1d05f4
I am integrating Laravel into a legacy php app. The login page used to directly post to verifyUser.php which also started a Symfony Session.
The new architecture now posts to a laravel api which makes a Guzzle post to verifyUser.php.
javascript:
$(document).ready(function(){
$('#signIn').submit(function(){
var a = $('#email').val();
$.post('/api/login', { //this used to post to verifyUser.php
Username: $('#email').val(),
Password: $('#password').val()
}, function(data){
if(data['credentials'] == true){
console.log('credentials true');
console.log(data['uri']);
window.location.href=data['uri'];
} else {
$('#errMsg').html(data['errMsg']);
$('.alert').show();
}
}, 'json');
return false;
});
controller functions:
public function authenticate(Request $request) //aka api/login endpoint
{
//...
$legacyRes = $this->authenticateLegacy($request);
//...
}
private function authenticateLegacy(Request $request)
{
$response = null;
try {
$response = $this->client->post('/admin/verifyUser.php', [
'form_params' => ['Username' => $request->get('Username'),
'Password' => $request->get('Password')]
]);
}
catch(Exception $exception){
Log::error('Errrererererer', [$exception->getMessage()]);
}
$body = (string)$response->getBody();
Log::info('BODY:', [$body]);
return $body;
}
I have left out verifyUser.php because I have tested it and it returns the expected results.
When using the browser, the session information doesn't seem to get set. But according to my post responses, everything should be working.
Is this because I am routing the request through guzzle?
Posting under my answer to show updated code:
private function authenticateLegacy(Request $request)
{
//...
//parse cookie id from guzzle response
$body = (string)$response->getBody();
$cookie = $response->getHeader('Set-Cookie'); //PHPSESSID=SOMEID; path=/
$cookieBite = explode(';', $cookie)[0]; ////PHPSESSID=SOMEID
$cookieId = explode('=', $cookieBite)[1];
$data = json_decode($body, true);
$data['session'] = $cookieId;
return $data;
}
In the action:
public function authenticate(Request $request)
{
//...
$legacyRes = $this->authenticateLegacy($request);
//...
// this will have the session id in the body but will also
// set the cookie for the client so I don't have
// to set document.cookie w/ js
return response($legacyRes, 200)
->withCookie('PHPSESSID', $legacyRes['session']);
}
I assume your legacy endpoint uses cookies to identify a user's session.
A successfull request to the legacy endpoint returns a Set-Cookie header.
Guzzle doesn't forward this Set-Cookie header from the API response to the browser - you'll have to program this behaviour into the "wrapping" application.
You will need to tell guzzle to explicitly pass the corresponding Cookie header to the legacy api (to maintain the user's login state) when sending any further requests.
In order to achieve this you'll need to save this cookie within your new application (i.e. in the user's session or in database) and then pass it within a Cookie header along with all further requests you make to the legacy API.
I have the next code, got directly from google reference (https://developers.google.com/identity/sign-in/web/backend-auth)
public function verifyFromAndroid($idToken=null) {
if(empty($idToken)) {
$idToken = self::SAMPLE_ID_TOKEN;
}
$client = new Google_Client(['client_id' => self::CLIENT_ID]);
$payload = $client->verifyIdToken($idToken);
if ($payload) {
print_r($payload);
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
var_dump($payload);
$this->lastError = "Invalid ID token";
return false;
}
}
But this method always returns false, even using a valid id token that is created and working using the oauthplayground online tool.
The next code works fine, using directly the GoogleAccessToken_Verify class. Can someone tell me why the official Google code doesn't work and yes my own code using the official Google-clien-php sdk?
try {
$verify = new Google_AccessToken_Verify();
$result = $verify->verifyIdToken($this->idToken);
if($result) {
print_r($result);
$friendlyData = $this->translateData($result, true);
if(!$friendlyData) {
return false;
}
return $friendlyData;
}
else {
$this->lastError = "Invalid token verification, no error code";
return false;
}
}
catch(UnexpectedValueException $ex) {
$this->lastError = "UnVaEx (Code {$ex->getCode()}): {$ex->getMessage()}";
return false;
}
try adding complete client ID
xxxxxxxxxxxxxx-xxxxx-yy-zz.apps.googleusercontent.com
while initiating the
$client = new Google_Client(['client_id' => self::CLIENT_ID]);
It should work i was also facing the same issue ...
Had a similar issue.Deleted my android app on firebase console and created a fresh app wirh debug key sha1.Then downloaded and replaced my google.json into my app.This fixed my issue.This has happened to me twice now. At times you just need to recreate the android app on firebase console.
Before you begin register your backend URL at https://developers.google.com/identity/sign-in/web/sign-in with Configure your project button and don't use any credidentials or api key in your code. After doing them your code should look like to this.
public function verifyFromAndroid($idToken=null) {
if(empty($idToken)) {
$idToken = self::SAMPLE_ID_TOKEN;
}
//As you notice we don't use any key as a parameters in Google_Client() API function
$client = new Google_Client();
$payload = $client->verifyIdToken($idToken);
if ($payload) {
print_r($payload);
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
var_dump($payload);
$this->lastError = "Invalid ID token";
return false;
}
}
I hope it helps.
I faced the same issue. After checking different PHP versions, I found that the google client library is working in PHP7.4 but not with PHP8.0.
Please try the below code after downgrading the version of PHP to 7.4
require_once 'vendor/autoload.php';
$id_token = $_POST['credential'];
$client = new Google_Client(['client_id' => $CLIENT_ID]); // Specify the CLIENT_ID of the app that accesses the backend
$payload = $client->verifyIdToken($id_token);
if ($payload) {
$userid = $payload['sub'];
// If request specified a G Suite domain:
//$domain = $payload['hd'];
} else {
// Invalid ID token
}
Or For development and debugging, you can call google oauth2 tokeninfo validation endpoint.
https://oauth2.googleapis.com/tokeninfo?id_token=$id_token
sorry if my language is not good.
i have a ionic app, this app send data with angular http.post to server my company, this is my script on server :
<?php
set_time_limit(120);
ini_set("max_execution_time",120);
date_default_timezone_set("Asia/Jakarta");
require_once("menu.php");
class serviceController extends menu
{
private $clientInput;
public function __construct($clientInput){
$this->clientInput = $clientInput;
$this->Controller();
}
private function getMenu($packageName){
parent::__construct($packageName);
echo json_encode(parent::menu());
}
private function Controller(){
$Decode = json_decode($this->clientInput);
if($Decode->id=="getMenu"){
$this->getMenu($Decode->packageName);
}else if($Decode->id=="Development"){
sleep(15);
echo '{"status":"1","info":"Success"}';
}else{
switch($Decode->packageName){
case "com.guava.manis.mobile.payment":{
$this->doRequest("http://xxx.xxx.xxx.xxx/multiflat_new.jsp");
break;
}
}
}
}
private function doRequest($target){
$ch = curl_init($target);
$input = str_replace(':"",',':"-",',str_replace(':false,',':"-",',str_replace(':0,',':"-",',$this->clientInput)));
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,$input);
curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Type:application/json'));
$response = curl_exec($ch);
$finalResponse = rtrim("1",$response);
echo $finalResponse;
}
}
$clientInput = file_get_contents("php://input");
new serviceController($clientInput);
this is my script on my ionic app :
httpPOST(){
var request = JSON.stringify(this.finalREQ);
console.log("httpPOST request : "+request);
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({ headers: headers });
return this.http.post(this.postUrl,request,options).timeout(50000)
}
when i send data json to server with field 'id' is 'Development' my script will be sleep 15 seconds, the problem is ionic app not receive response from server, but if i change sleep <=7 seconds it's works, my question is how to create ionic app can wait response >=7 seconds ?, but if my scripts on server i move to localhost, dan i send data to localhost it's works perfectly, where the problem ?, on my server scripts, my ionic app scripts, or on my configuration of apache ?
I am developing an android application that uses the PHP/MySQL to send data from app to server in order to register/login users. I already wrote the Javascript and PHP files to send and receive JSON data an insert it into MySQL database. The problem I have is how to handle different responses from PHP.
Exemple:
<?php
//decode json object
$json = file_get_contents('php://input');
$obj = json_decode($json);
//variables
$user_firstname = $obj->{'user_firstname'};
$user_lastname = $obj->{'user_lastname'};
$user_email = $obj->{'user_email'};
$user_password = $obj->{'user_password'};
if([variables] != null){
//check for an existing email in db
mysql_query("Check if email exists");
if(email exist){
//pass a response to java file
return user_exists;
die();
}else{
//success
return success;
}
}
?>
All I want is to handle those different return values in order to interact with the user inside the android app.
I think you should user HTTP response codes for this. For example, your php script will return HTTP 200 - OK when user successfully created and HTTP 409 Conflict when user already exists. This is how RESTfull APIs usually works this. On Android you'll have to check the status code and decide what to do.
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpget = new HttpPost("http://www.google.com/");
HttpResponse response = httpclient.execute(httpget);
int statusCode = response.getStatusLine().getStatusCode();
You can craft a json response by creating an associative array and passing it to json_encode() which will return a string that you can echo to the java client. Don't forget to set the appropriate Content-Type header using the header() function. It's also a good idea to set the HTTP response code appropriately. I'm picturing something like this:
$responseArray = array('response' => 'success'); // or 'user_exists'
$responseJson = json_encode($responseArray);
header('HTTP/1.1 200 OK'); // or 4xx FAIL_TEXT on failure
header('Content-Type: application/json');
echo $responseJson;
You'll then have to parse this response on the java client.