Laravel 5.1 csrftoken curl from paypal - php

How i Can add or somethink do with csrftoken when paypal send post on my website.
My error code:
TokenMismatchException in VerifyCsrfToken.php line 53.
Here code:
public function getPaypal(Request $request)
{
$uri = $request->all();
if(isset($uri['tx']))
{
$pp_hostname = "www.sandbox.paypal.com"; // Change to www.sandbox.paypal.com to test against sandbox
// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-synch';
$tx_token = $uri['tx'];
$auth_token = "EHNebv....e";
$req .= "&tx=$tx_token&at=$auth_token";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://$pp_hostname/cgi-bin/webscr");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $req);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
//set cacert.pem verisign certificate path in curl using 'CURLOPT_CAINFO' field here,
//if your server does not bundled with default verisign certificates.
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Host: $pp_hostname"));
$res = curl_exec($ch);
curl_close($ch);
}

According to Laravel Docs: http://laravel.com/docs/5.1/routing#csrf-protection.
Excluding URIs From CSRF Protection
Sometimes you may wish to exclude a set of URIs from CSRF protection.
For example, if you are using Stripe to process payments and are
utilizing their webhook system, you will need to exclude your webhook
handler route from Laravel's CSRF protection.
You may exclude URIs by adding them to the $except property of the
VerifyCsrfToken middleware:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'paypal/*',
];
}
Let me know if it is still not clear.

You don't need to completely disable the middleware just go to VerifyCrsfToken file in app\Http\Middle then edit the protected array $except and include and entry of the route paypal is posting to.
protected $except = [
/paypal/data,
];

TokenMismatchException is a Laravel error, not PayPal. With every POST request, you need to send a _token value through with it.
If you are sending this through a form, simply echo csrf_field() into your form template.
If you are sending the request from something other than Laravel, you can disable the CSRF protection on that route. Read more about Middleware here: http://laravel.com/docs/5.1/middleware
Read more about it here: http://laravel.com/docs/5.1/routing#csrf-protection

Related

How to get Laravel's CSRF Token from Another Website?

I want to get a csrf token from another web's form. I've tried to get that token with cUrl. I guess that was success, but I think the real problem is that another web's form couldn't refresh the Token until the form is well filled and submitted while my web form is always refresh that token every time I refresh the page.
So this is my cUrl code:
<?php
function bacaHTML($url)
{
// inisialisasi CURL
$data = curl_init();
// setting CURL
curl_setopt($data, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($data, CURLOPT_URL, $url);
// menjalankan CURL untuk membaca isi file
$hasil = curl_exec($data);
curl_close($data);
return $hasil;
}
$kodeHTML = bacaHTML('http://bla-bla-bla.id/yeah');
$pecah = explode('<form action="http://bla-bla-bla.id/yeah" name="donasi" id="donasi" method="post">', $kodeHTML);
$pecahLagi = explode('<input type="hidden" name="user_id" id="user_id" value="">', $pecah[1]);
echo $pecahLagi[0];
?>
And i got this
<input type="hidden" name="_token" value="qRIDbrYH4MvFdhIe2sP9Rtp17C6SaDf9quSsbIOH">
But that token is not generated until that web form well filled while in my form was generated as I said before so my form can't pass data to that web form. For your information, that web was builder with Laravel. Can anybody help me? And sorry for my bad English. I'm new to programming
hi the right way is disable csrf token on route in
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
//add route here
];
}

I am trying to hit a certain local MPESA Payment API but am getting an error

I am trying to get a response from MPESA payment API using laravel but I am getting an error . My code is as below
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class MPESA_AUTH extends Controller
{
public function Authorize(){
$url = 'https://sandbox.safaricom.co.ke/oauth/v1/generate?grant_type=client_credentials';
$CONSUMER_KEY= 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$CONSUMER_SECRET= 'xxxxxxxxxxxx';
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
$credentials = base64_encode($CONSUMER_KEY,$CONSUMER_SECRET);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Basic '.$credentials)); //setting a custom header
curl_setopt($curl, CURLOPT_HEADER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$curl_response = curl_exec($curl);
$curl_json=json_decode($curl_response);
return $curl_json;
}
}
The error am getting is as below
The Base controller uses Illuminate\Routing\Controller trait which has an 'authorize()' function. Your function declaration is clashing with it.
Change your controller method name to anything else(other than 'authorize') and you should be good to go
You should use a different function name in place of "Authorize". This is because "authorize" in controllers is a preserved name used in the parent class Controller.

Restler : make a get request with security key in post parameter

I would like to call a rest function of my api with the GET protocol but I didn't succeed to put the security key of restler as a post parameter.
example:
/index.php/myrestapi/method.json?name=test
post field : Array('key'=>'mykey')
$session = curl_init('<mydomainurl>/index.php/myrestapi/method.json?name=test');
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, array('key'=>'mykey');
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($session);
Myrestapi.php function:
protected function getMethod($name){
return $name;
}
What is wrong?!
Thanks in advance for your help!
Kevin
security key should also be part of get parameter
<mydomainurl>/index.php/myrestapi/method.json?name=test&key=mykey
Then need to handle that with iAuthenticate.
For more details see e.g. Protected API of restler.

Is per-request, stateless HTTP Basic/Digest authentication possible in CakePHP 2.0?

The manual is unclear as to how to implement this (it assumes you already know what exactly you're doing and in some cases feels like an afterthought), and I've been scratching my head for a fair while trying to figure it out.
The problem: authentication via HTTP auth headers for all API requests
As far as I've been able to test, I can use Basic auth and the normal form based login in CakePHP, but only by first hitting up the login action I define in the Auth component. This is fine when I'm accessing the site directly, and works as expected (with the exception of Digest, which appears to be utterly buggered). Via cURL, though, I've had no luck unless I'm already logged in.
Obviously, for an API, this is far from ideal. I don't want to post a request to /login before doing what I want to do, and I can't expect a user to log in manually so Cake has a cookie to read. It needs to be stateless.
Any attempt to supply authentication credentials along with each request I make (via cURL) is ignored and I get a 403 error in return. Neither the login method or any of the Auth classes are touched.
What do I need to do to make Cake behave like an actual API and allow me to authorise statelessly on a per request basis? Am I going to have to roll my own solution?
I have a centralized API that allows for user authentication via HTTP Digest and requires users to login for many user related functions. The way CakePHP forces a login is by checking if the action requires login, redirecting to your login action (defaults to /users/login), then you can redirect back.
I created my API by doing the following:
//Config/routes.php
///////////////////////////
/**
* Users Controller routes for REST API
*/
Router::mapResources('users');
/**
* Parses extensions for data serialization
*/
Router::parseExtensions();
//Controller/UserController.php
////////////////////////////////
<?php
App::uses('DigestAuthenticate', 'Controller/Component/Auth/');
class UsersController extends AppController {
var $name = 'Users';
//Login callback
function login() {
//dont render for login, just a call back for auth
$this->autoRender = false;
if ($this->Auth->login()) {
$this->redirect($this->Auth->redirect());
}
}
//GET /users.[xml|json]
//this is the basic call that tests user authentication
//basically a login then echo
function index() {
if ($this->Auth->login()) {
$user = $this->Auth->user();
$this->User->id = $user['id'];
$this->User->saveField('last_login', date('Y-m-d H:i:s'));
$this->set('response', array(
'response' => array(
'code' => 'users_auth_success',
'message' => 'User has passed authentication',
'data' => $user
)
));
//will serialize to xml or json based on extension
$this->set('_serialize', 'response');
}
}
}
?>
You can then use this API in something like:
$c = curl_init($uri . '.' . $this->_format);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_USERPWD, $login['user'] . ':' . $login['pass']);
curl_setopt($c, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
$response = curl_exec($c);
$info = curl_getinfo($c);
curl_close($c);
if($info['http_code'] == $this->_http_codes['OK']) {
//success
if($this->_format == 'xml')
$response = Xml::toArray(Xml::build($response));
else//JSON
$response = json_decode($response);
return $response['response']['data'];
} else if($info['http_code'] == $this->_http_codes['Unauthorized']) {
return false;
} else {
return null;
}

Unable to fetch my schedule data from my schools site. Login with cURL won't work

Edit: Why the minus one?
What I am trying to do is the following:
I am trying to login to my school site using cURL and grab the schedule to use it for my AI.
So I need to login using my pass and number, but the form on the school site also needs a hidden 'token'.
<form action="index.php" method="post">
<input type="hidden" name="token" value="becb14a25acf2a0e697b50eae3f0f205" />
<input type="text" name="user" />
<input type="password" name="password" />
<input type="submit" value="submit">
</form>
I'm able to successfully retrieve the token. Then I try to login, but it fails.
// Getting the whole website
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.school.com');
$data = curl_exec($ch);
// Retrieving the token and putting it in a POST
$regex = '/<regexThatWorks>/';
preg_match($regex,$data,$match);
$postfields = "user=<number>&password=<secret>&token=$match[1]";
// Should I use a fresh cURL here?
// Setting the POST options, etc.
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields);
// I won't use CURLOPT_RETURNTRANSFER yet, first I want to see results.
$data = curl_exec($ch);
curl_close($ch);
Well... It doesn't work...
Is it possible the token changes every curl_exec? Because the site doesn't recognize the script the second time...
Should I create a new cURL instance(?) for the second part?
Is there another way to grab the token within 1 connection?
Cookies?
What's the error message you get? Independently of that; your school's website might check the referrer header and make sure that the request is coming from (an application pretending to be...) its login page.
This is how I solved it. The problem was probably the 'not-using-cookies' part.
Still this is probably 'ugly' code, so any improvements are welcome!
// This part is for retrieving the token from the hidden field.
// To be honest, I have no idea what the cookie lines actually do, but it works.
$getToken= curl_init();
curl_setopt($getToken, CURLOPT_URL, '<schoolsite>'); // Set the link
curl_setopt($getToken, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($getToken, CURLOPT_RETURNTRANSFER, 1); // Return only as a string
$data = curl_exec($token); // Perform action
// Close the connection if there are no errors
if(curl_errno($token)){print curl_error($token);}
else{curl_close($token);}
// Use a regular expression to fetch the token
$regex = '/name="token" value="(.*?)"/';
preg_match($regex,$data,$match);
// Put the login info and the token in a post header string
$postfield = "token=$match[1]&user=<number>&paswoord=<mine>";
echo($postfields);
// This part is for logging in and getting the data.
$site = curl_init();
curl_setopt($site, CURLOPT_URL, '<school site');
curl_setopt($site, CURLOPT_COOKIEJAR, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_COOKIEFILE, 'cookies.txt'); // Magic
curl_setopt($site, CURLOPT_POST, 1); // Use POST (not GET)
curl_setopt($site, CURLOPT_POSTFIELDS, $postfield); // Insert headers
$forevil_uuh_no_GOOD_purposes = curl_exec($site); // Output the results
// Close connection if no errors
if(curl_errno($site)){print curl_error($site);}
else{curl_close($site);}
As you're building a scraper, you can create your own classes to work for what you need to do in your domain. You can start by creating your own set of request and response classes that deal with what you need to deal with.
Creating your own request class will allow you to implement the curl request the way you need it. Creating your own response class can you help you access/parse the returned HTML.
This is a simple usage example of some classes I've created for a demo:
# simple get request
$request = new MyRequest('http://hakre.wordpress.com/');
$response = new MyResponse($request);
foreach($response->xpath('//div[#id="container"]//div[contains(normalize-space(#class), " post ")]') as $node)
{
if (!$node->h2->a) continue;
echo $node->h2->a, "\n<", $node->h2->a['href'] ,">\n\n";
}
It will return my blogs posts:
Will Automattic join Dec 29 move away from GoDaddy day?
<http://hakre.wordpress.com/2011/12/23/will-automattic-join-dec-29-move-away-from-godaddy-day/>
PHP UTF-8 string Length
<http://hakre.wordpress.com/2011/12/13/php-utf-8-string-length/>
Title belongs into Head
<http://hakre.wordpress.com/2011/11/02/title-belongs-into-head/>
...
Sending a get request then is easy as pie, the response can be easily accessed with an xpath expression (here SimpleXML). XPath can be useful to select the token from the form field as it allows you to query data of the document more easily than with a regular expression.
Sending a post request was the next thing to build, I tried to write a login script for my blog and it turned out to work quite well. I needed to parse response headers as well, so I added some more routines to my request and response class.
# simple post request
$request = new MyRequest('https://example.wordpress.com/wp-login.php');
$postFields = array(
'log' => 'username',
'pwd' => 'password',
);
$request->setPostFields($postFields);
$response = new MyResponse($request->returnHeaders(1)->execute());
echo (string) $response; # output to view headers
Considering your scenario you might want to edit your own request class to better deal with what you need, mine already uses cookies as you're using them, too. So some code based on these classes for your scenario could look like:
# input values
$url = '<schoolsite>';
$user = '<number>';
$password = '<secret>';
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($url));
$token = (string) $response->xpath('//input[#name="token"]/#value');
# execute the second login post request
$request = new MyRequest($url);
$postFields = array(;
'user' => $user,
'password' => $password,
'token' => $token
);
$request->setPostFields($postFields)->execute();
Demo and code as gist.
If you want to further improve this, the next step is that you create yourself a class for the "school service" that you make use of to fetch the schedule from:
class MySchoolService
{
private $url, $user, $pass;
private $isLoggedIn;
public function __construct($url, $user, $pass)
{
$this->url = $url;
...
}
public function getSchedule()
{
$this->ensureLogin();
# your code to obtain the schedule, e.g. in form of an array.
$schedule = ...
return $schedule;
}
private function ensureLogin($reuse = TRUE)
{
if ($reuse && $this->isLoggedIn) return;
# execute the first get request to obtain token
$response = new MyResonse(new MyRequest($this->url));
$token = (string) $response->xpath('//input[#name="token"]/#value');
# execute the second login post request
$request = new MyRequest($this->url);
$postFields = array(;
'user' => $this->user,
'password' => $this->password,
'token' => $token
);
$request->setPostFields($postFields)->execute();
$this->isLoggedIn = TRUE;
}
}
After you've nicely wrapped the request/response logic into your MySchoolService class you only need to instantiate it with the proper configuration and you can easily use it inside your website:
$school = new MySchoolService('<schoolsite>', '<number>', '<secret>');
$schedule = $school->getSchedule();
Your main script only uses the MySchoolService.
The MySchoolService takes care of making use of MyRequest and MyResponse objects.
MyRequest takes care of doing HTTP requests (here with cUrl) with cookies and such.
MyResponse helps a bit with parsing HTTP responses.
Compare this with a standard internet browser:
Browser: Handles cookies and sessions, does HTTP requests and parses responses.
MySchoolService: Handles cookies and sessions for your school, does HTTP requests and parses responses.
So you now have a school browser in your script that does what you want. If you need more options, you can easily extend it.
I hope this is helpful, the starting point was to prevent written the same lines of cUrl code over and over again and as well to give you a better interface to parse return values. The MySchoolService is some sugar on top that make things easy to deal with in your own website / application code.

Categories