Curl PUT Request and empty request data (rest api) - cakephp-3.x

I am trying to make a PUT request, in order to edit some user's data, but I am receiving empty data instead of what I'm sending through my request.
I have tried with postman (a chrome plugin) and with a custom php snippet:
?php
$process = curl_init('http://localhost/myapp/api/users/1.json');
$headers = [
'Content-Type:application/json',
'Authorization: Basic "...=="'
];
$data = [
'active' => 0,
'end_date' => '01/01/2018'
];
curl_setopt($process, CURLOPT_HTTPHEADER, $headers);
curl_setopt($process, CURLOPT_TIMEOUT, 30);
curl_setopt($process, CURLOPT_PUT, 1);
curl_setopt($process, CURLOPT_POSTFIELDS, $data);
curl_setopt($process, CURLOPT_RETURNTRANSFER, TRUE);
$return = curl_exec($process);
curl_close($process);
print_r($return);
This is the code that I'm using cakephp-side:
class UsersController extends AppController
{
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
....
public function edit($id = null)
{
debug($_SERVER['REQUEST_METHOD']);
debug($this->request->data);
die;
}
....
And this is what it outputs:
/src/Controller/UsersController.php (line 318)
'PUT'
/src/Controller/UsersController.php (line 319)
[]
I am confused... similar code is working for a POST request and the add action... what is wrong with this code?

Two problems.
When using CURLOPT_PUT, you must use CURLOPT_INFILE to define the data to send, ie your code currently doesn't send any data at all.
CURLOPT_PUT
TRUE to HTTP PUT a file. The file to PUT must be set with CURLOPT_INFILE and CURLOPT_INFILESIZE.
http://php.net/manual/en/function.curl-setopt.php
You are defining the data as an array.
CURLOPT_POSTFIELDS
[...] If value is an array, the Content-Type header will be set to multipart/form-data.
http://php.net/manual/en/function.curl-setopt.php
So even if the data would be sent, it would be sent as form data, which the request handler component wouldn't be able to decode (it would expect a JSON string), even if it would try to, which it won't, since your custom Content-Type header would not be set unless you'd pass the data as a string.
Long story short, use CURLOPT_CUSTOMREQUEST instead of CURLOPT_PUT, and set your data as a JSON string.
curl_setopt($process, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($process, CURLOPT_POSTFIELDS, json_encode($data));
Your Postman request likely has a similar problem.

Related

I need to pass user information from registration page to 2 different controllers

when user register, i need to pass registration field value to other controller also. this other controller will send information to outside api as post to register other websites.
I try to redirect with data but i think i just totally lost. this is my second controller
public function registerUser()
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://api01.oriental-game.com:8085/register");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->xtoken);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
"username" => "test2",
"country" => "Korea",
"fullname" => "Hihi User",
"language" => "kr",
"email" => "myuser123#test.com",
"birthdate" => "1992-02-18"
)));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec($ch);
curl_close($ch);
}
when user register to our site, it will automatically create account in our own site and other 2 websites through their register api.
thanks in advance for your help.
Instead of redirecting from function to function by means of HTTP redirects why not pass the form-data from your register form to a /register-user route and in the routes corresponding controller method catch the form data there.
Your form will post to something like this so make sure you have a route to first controller:
Route::get('/register-user', 'RegisterControllerNameHere#index');
Inside the first controllers function call the registerUser() in the second Controller like:
public function registerUser(Illuminate\Http\Request $request) {
(new \App\Http\Controllers\SecondControllerName)->registerUser($request>all());
}
Also allow for parameters to be passsed to the second controller:
public function registerUser($userData) // add parameter
Now $userData will have the same data as the first controller which you can pass to your API call.
Does this help answer your question?

Login to using another API in server in laravel

Argument 1 passed to Illuminate\Auth\SessionGuard::login() must be an
Instance of Illuminate\Contracts\Auth\Authenticatable, instance of
Illuminate\Http\Request given
The question is not very descriptive. But from the title and the error, I am assuming you are trying to login to your application using another application login API.
For that, you need to build your own custom authentication system, middlewares for protecting authorized routes etc., as laravel default Auth will not work since it depends on Authenticatable contract which in return depends on user modal of the applicaiton.
If that another API, happened to be one of the Social media, in that case, you can use socialite driver.
public function userlogin(Request $request){
$validatedData = $request->validate([
'email' => 'required|max:255',
'pwd' => 'required|max:255|min:3',
]);
$data = [ "username"=>$request->email,
"password"=>$request->pwd,
];
$ch = curl_init("http://localhost/getuus/login");
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type:application/json']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
$result = collect(json_decode($result));
if ($result['status'] == 1) {
$Auth = new Auth; $Auth::login($request, true);
return redirect('home');
}
else{
return view('userlogin');
}
}

Run controller PHP codeigniter function with ajax

I'm trying to run function getVideos() from my controller using ajax but I got a 404 error.
Is there any problem with the url or the route?
videos.php (Controller)
public function getVideos(){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
echo json_encode($ch);
}
main.js
$.get("videos/getVideos", function(data, status){
console.log(data);
});
routes.php
$route["videos"] = "videos/get_videos/";
This probably help
site_url('videos/getVideos')
or write the full url in your ajax
mydomain.com/videos/getVideos
and by the way you don't need to create a manual route for it because codeigniter framework allow to auto generate a route for you via controller and method.
Help this give you an idea.

SQLSTATE[42S02]: Base table or view not found Error with laravel curl

I have written two laravel apps. FirstApp and CryptoApp ( name of apps respectively )
In which I send encrypted text to a function called ( Decrypt ) in CryptoApp that is supposed to return decrypted text
In FirstApp i am sending a curl POST request with the encrypted text to CryptoApp
cURL post code: inside FirstApp
private function DecryptApi($data)
{
$ch = curl_init(); // initiate curl
$url = "http://crypto.dev/Decrypt"; // where you want to post data
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST, true); // tell curl you want to post something
curl_setopt($ch, CURLOPT_POSTFIELDS, "data=".$data); // define what you want to post
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // return the output in string format
$output = curl_exec ($ch); // execute
curl_close ($ch); // close curl handle
return $output; // show output
}
The Route : Route::post('/Decrypt','CryptoController#Decrypt');
The Function :
public function Decrypt(Request $request)
{
$crypt = Crypto::find(1);
return openssl_decrypt($request['data'],"AES-256-CBC",$crypt->secretKey,0,$crypt->iv);
}
the Error i am getting is : "SQLSTATE[42S02]: Base table or view not found: 1146 Table 'laravel_firstapp.crypto' doesn't exist (SQL: select * from crypto where crypto.id = 1 limit 1)"
this error has confused me because i know that FirstApp does not have a table named 'crypto' but CryptoApp does, why is laravel not returning the text i want ?
make sure you have table in your laravel_firstapp database. Run migration if any.
also if your table name is not crypto u can use protected $table = 'your table' in your model
You have to check if the crypto table already exists in your CryptoApp, also check .env file in your CryptoApp, maybe it's configured with FirstApp database, it should be:
CryptoApp .env file
...
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=CryptoApp_database
DB_USERNAME=user
DB_PASSWORD=****
...

Basecamp API authentication with OAuth2: internal checksum failed error

I'm trying to write a CodeIgniter controller to handle OAuth2 authentication for the 37signals' Basecamp API.
The problem is I keep encountering the 'internal checksum failed' error, when trying to connect (via cURL) to https://launchpad.37signals.com/authorization.json, providing the Auth Token in a HTTP header.
Here's the index and _authcode functions from my controller class:
<?php
// constants:
// BC_REQUEST_URL = 'https://launchpad.37signals.com/authorization/new'
// BC_TOKEN_URL = 'https://launchpad.37signals.com/authorization/token'
// ...
public function index() {
// if get data is set.
if ($this->input->get()) {
// if auth code is provided via GET, switch to _authcode method.
if ( $code = $this->input->get('code') ) {
return $this->_authcode($code);
}
// On error, kill yourself.
if ( $error = $this->input->get('error') ) {
die($error);
}
}
// redirect to 37 signals to get an authcode
header("Location: ".BC_REQUEST_URL."?type=web_server&client_id=".BC_CLIENT_ID."&redirect_uri=".BC_REDIRECT_URL."");
}
// handles the Authentication code that is returned by 37 Signals.
private function _authcode($code) {
// set vars to POST
$vars = array(
'type' => 'web_server',
'client_id' => BC_CLIENT_ID,
'redirect_uri' => BC_REDIRECT_URL,
'client_secret' => BC_CLIENT_SECRET,
'code' => $code
);
// make a request for the access_token
$url = BC_TOKEN_URL;
$c = curl_init($url);
curl_setopt($c, CURLOPT_POST, true);
curl_setopt($c, CURLOPT_POSTFIELDS, http_build_query($vars));
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($c));
curl_close($c);
unset($c,$url);
// get the access vars from this request
$expiry_seconds = $response->expires_in; // default: 1209600 (14 days)
$refresh_token = $response->refresh_token;
$access_token = $response->access_token;
unset($response);
// make a separate request to get user info for current user.
$url = "https://launchpad.37signals.com/authorization.json";
$c = curl_init($url);
curl_setopt($c, CURLOPT_HTTPHEADER, array(
"Authorization: Bearer <$access_token>",
"Content-Type: application/json; charset=utf-8",
"User-Agent: MyApp (http://myapp.example.com)"
));
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
$response = json_decode(curl_exec($c)); // reply from 37 signal auth
curl_close($c);
unset($c,$url);
echo "response obj = " . print_r($response,1);
/* prints: response obj = stdClass Object ( [error] => OAuth token could not be verified. The internal checksum failed, so the token data was somehow mangled or tampered with. ) */
// get the user data from this request
// $expires_at = $response->expires_at; // the timestamp for when this request expires
// $identity = $response->identity; // the current user
// $accounts = $response->accounts; // list of accounts we can access
// unset($response);
// store the response data to the database for easy recall.
// $this->db->query("REPLACE INTO `sometable` SET `key1`='value', `key2`='value');
}
// ...
?>
I ran into this error when saving the auth token in the database with varchar(255). Basecamp's auth token has some checksum data which brings the token over 255 characters.
You don't appear to be pulling it from a database in your example, so this might not affect you, however checking for Basecamp's token being cut off is what I would first look at.
Optionally, remove the <> characters around your $access_token when setting the Bearer header.

Resources