payload is invalid for laravel_session decrypt - laravel

I'm trying to decrypt laravel_session but the following error occur:
An error has occurred: The payload is invalid.
simply I'm using Rachet and I'm trying to call the authorized user, so I got the cookies in httpRequest using the following:
public function onOpen(ConnectionInterface $conn) {
$this->clients[$conn->resourceId] = new Client();
$this->clients[$conn->resourceId]->conn = $conn;
$cookiesRaw = $conn->httpRequest->getHeader('Cookie');
$cookies = [];
if(count($cookiesRaw))
{
$cookies = \GuzzleHttp\Psr7\parse_header($cookiesRaw)[0]; // Array of cookies
}
// Get the laravel's one
$laravelCookie = $cookies[Config::get('session.cookie')];
$idSession = Crypt::decrypt($laravelCookie);
echo "\n cookie is ";
print_r($idSession);
}
The Crypt::decrypt($laravelCookie); is causing the error, I've tried to use:
$cookie_contents = json_decode( base64_decode( $laravelCookie, true ));
$value = base64_decode( $cookie_contents->value );
$iv = base64_decode( $cookie_contents->iv );
$clear = unserialize( \openssl_decrypt($value, \Config::get( 'app.cipher' ), \Config::get( 'app.key' ), OPENSSL_RAW_DATA, $iv));
echo "Cookie contents (Session ID): $value\n";
but it is also causing The payload is invalid.
How can I decrypt this laravel_session in order to get user session id !
I want to get the Auth user via this session.
I've searched a lot in stack-overflow and google, but all the cases didn't match mine.
Note: I'm using SESSION_DRIVER=file

Laravel provides a way to grab your session id:
use Illuminate\Support\Facades\Session;
$sessionid = Session::getId();

Related

How to retrieve draft grade from Google Classroom using api in php

I want to read draft grade marks from Google Classroom using API for a project. But I can't find out the draft grade. Already I've added some code to the quickstart.php file:
require __DIR__ . '/vendor/autoload.php';
// if (php_sapi_name() != 'cli') {
// throw new Exception('This application must be run on the command line.');
// }
/**
* Returns an authorized API client.
* #return Google_Client the authorized client object
*/
function getClient()
{
$client = new Google_Client();
$client->setApplicationName('Google Classroom API PHP Quickstart');
$client->setScopes(array(
Google_Service_Classroom::CLASSROOM_COURSES,
Google_Service_Classroom::CLASSROOM_STUDENT_SUBMISSIONS_STUDENTS_READONLY,
Google_Service_Classroom::CLASSROOM_ROSTERS)
);
$client->setAuthConfig(__DIR__ .'/credentials.json');
$client->setAccessType('offline');
$client->setPrompt('select_account consent');
// Load previously authorized token from a file, if it exists.
// The file token.json stores the user's access and refresh tokens, and is
// created automatically when the authorization flow completes for the first
// time.
$tokenPath = 'token.json';
if (file_exists($tokenPath)) {
$accessToken = json_decode(file_get_contents($tokenPath), true);
$client->setAccessToken($accessToken);
}
// If there is no previous token or it's expired.
if ($client->isAccessTokenExpired()) {
// Refresh the token if possible, else fetch a new one.
if ($client->getRefreshToken()) {
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
} else {
// Request authorization from the user.
$authUrl = $client->createAuthUrl();
printf("Open the following link in your browser:\n%s\n", $authUrl);
print 'Enter verification code: ';
$authCode = trim(fgets(STDIN));
// Exchange authorization code for an access token.
$accessToken = $client->fetchAccessTokenWithAuthCode($authCode);
$client->setAccessToken($accessToken);
// Check to see if there was an error.
if (array_key_exists('error', $accessToken)) {
throw new Exception(join(', ', $accessToken));
}
}
// Save the token to a file.
if (!file_exists(dirname($tokenPath))) {
mkdir(dirname($tokenPath), 0700, true);
}
file_put_contents($tokenPath, json_encode($client->getAccessToken()));
}
return $client;
}
$optParams = array(
'pageSize' => 1000
);
// Copyright 2021 Google LLC.
// SPDX-License-Identifier: Apache-2.0
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Classroom($client);
// set these parameters:
// 328776504166 <- It is my course id
// 339429593407 <- It is my course work id
$courseId = "328776504166";
$courseWorkId = "339429593407";
$results = $service->courses_courseWork_studentSubmissions->listCoursesCourseWorkStudentSubmissions($courseId, $courseWorkId);
foreach ($results->studentSubmissions as $r => $submission) {
$student = $service->courses_students->get($courseId, $submission->userId);
$studentName = $student->profile->name->fullName;
print("<br>Student Name: ".$studentName . ": ");
print("<br>Draft Grade: ".$submission->draftGrade. "\n");
print("<br>Course Work Id: ".$submission->courseWorkId. "\n");
echo '<pre>';
print_r($submission);
}
Then when I run quickstart.php at localhost the following problems can be seen:
Fatal error: Uncaught Google_Service_Exception: { "error": { "code": 400, "message": "Precondition check failed.", "errors": [ { "message": "Precondition check failed.", "domain": "global", "reason": "failedPrecondition" } ], "status": "FAILED_PRECONDITION" } } in C:\xampp\htdocs\api\vendor\google\apiclient\src\Google\Http\REST.php:118 Stack trace: #0
I can't find my wrong. How to solve this problem? please give me some suggestions.
As stated in the documentation:
Students cannot see draft grades
This is why a student who intents to retrieve a draft grade will obtain a
403 - "Insufficient Permission" error.

Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature

I've been searching for this for hours, I hope someone here can help.
I built a subscription based site on Laravel and PayPal subscriptions using the PayPal PHP SDK.
Everything works perfectly except on thing:
I created a webhook for when a user cancels the payment on his end. I'm getting this error:
Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature.{"name":"VALIDATION_ERROR","message":"Invalid data provided","debug_id":"7225cebfec35a","information_link":"https://developer.paypal.com/docs/api/webhooks/#errors","details":[{"field":"webhook_id","location":"body","issue":"Required field cannot be blank"}],"links":[]}
Here is my code:
public function webhook()
{
/**
* Receive the entire body that you received from PayPal webhook.
*/
$bodyReceived = file_get_contents('php://input');
// Receive HTTP headers that you received from PayPal webhook.
$headers = getallheaders();
/**
* Uppercase all the headers for consistency
*/
$headers = array_change_key_case($headers, CASE_UPPER);
$signatureVerification = new \PayPal\Api\VerifyWebhookSignature();
$signatureVerification->setWebhookId(env('PAYPAL_WEBHOOK_ID'));
$signatureVerification->setAuthAlgo($headers['PAYPAL-AUTH-ALGO']);
$signatureVerification->setTransmissionId($headers['PAYPAL-TRANSMISSION-ID']);
$signatureVerification->setCertUrl($headers['PAYPAL-CERT-URL']);
$signatureVerification->setTransmissionSig($headers['PAYPAL-TRANSMISSION-SIG']);
$signatureVerification->setTransmissionTime($headers['PAYPAL-TRANSMISSION-TIME']);
$webhookEvent = new \PayPal\Api\WebhookEvent();
$webhookEvent->fromJson($bodyReceived);
$signatureVerification->setWebhookEvent($webhookEvent);
$request = clone $signatureVerification;
try {
$output = $signatureVerification->post($this->apiContext);
} catch(\Exception $ex) {
//This is where it fails
print_r($ex->getMessage());
exit(1);
}
$verificationStatus = $output->getVerificationStatus();
$responseArray = json_decode($request->toJSON(), true);
$event = $responseArray['webhook_event']['event_type'];
if ($verificationStatus == 'SUCCESS')
{
switch($event)
{
case 'BILLING.SUBSCRIPTION.CANCELLED':
case 'BILLING.SUBSCRIPTION.SUSPENDED':
case 'BILLING.SUBSCRIPTION.EXPIRED':
case 'BILLING_AGREEMENTS.AGREEMENT.CANCELLED':
// $user = User::where('payer_id',$responseArray['webhook_event']['resource']['payer']['payer_info']['payer_id'])->first();
$this->updateStatus($responseArray['webhook_event']['resource']['payer']['payer_info']['payer_id'], 0,1);
break;
}
}
echo $verificationStatus;
exit(0);
}
And here is the $this->apiContext:
trait PayPalApiCredentialsTrait {
private $apiContext;
public function setCredentials()
{
$this->apiContext = new \PayPal\Rest\ApiContext(
new \PayPal\Auth\OAuthTokenCredential(
env('PAYPAL_CLIENT_ID'), // ClientID
env('PAYPAL_CLIENT_SECRET') // ClientSecret
)
);
$this->apiContext->setConfig(
array(
'mode' => env("PAYPAL_MODE"),
'log.LogEnabled' => true,
'log.FileName' => '../PayPal.log',
'log.LogLevel' => 'INFO', // PLEASE USE `INFO` LEVEL FOR LOGGING IN LIVE ENVIRONMENTS
)
);
}
}
This is the error I get from the paypal.log:
[01-09-2020 15:54:18] PayPal\Core\PayPalHttpConnection : INFO: POST https://api.sandbox.paypal.com/v1/oauth2/token
[01-09-2020 15:54:18] PayPal\Core\PayPalHttpConnection : INFO: Response Status : 200
[01-09-2020 15:54:18] PayPal\Core\PayPalHttpConnection : INFO: POST https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature
[01-09-2020 15:54:19] PayPal\Core\PayPalHttpConnection : INFO: Response Status : 400
[01-09-2020 15:54:19] PayPal\Core\PayPalHttpConnection : ERROR: Got Http response code 400 when accessing https://api.sandbox.paypal.com/v1/notifications/verify-webhook-signature. {"name":"VALIDATION_ERROR","message":"Invalid data provided","debug_id":"26b12ee43cddd","information_link":"https://developer.paypal.com/docs/api/webhooks/#errors","details":[{"field":"webhook_id","location":"body","issue":"Required field cannot be blank"}],"links":[]}
I must mention that everything else works fine.
Creating plans, agreements, cancelling the both, showing active plans, and more...
Everything works smoothly.
This is the only thing that I can't seem to fix.
If anyone could figure this out for me, I'd really appreciate it.
Thank you!
The PayPal-PHP-SDK is deprecated and no longer maintained; it should not be used for new integrations. Its implementation of billing plans and subscriptions is old, and not compatible with the current version of the Subscriptions API.
In its place, a direct HTTPS integration (no SDK) should be used for Subscriptions, and for verifying webhooks.
(For the one time payment use case, there is a new v2 Checkout-PHP-SDK https://developer.paypal.com/docs/api/rest-sdks/ )

Wordpress Auth + Nonces + Ajax + No Templating - Cookie nonce is invalid

I understand the process of using nonces when I create my own templates.
But I am developing a ReactJS App which uses ONLY the Wordpress REST API for pulling data, so the user never gets to the index.php, but does Ajax calls to the WP Rest Api.
Now I cannot get the nonce stuff to work.
This is what I have done so far:
I added the following endpoints:
register_rest_route('frontend', '/customer/', array(
'methods' => 'GET',
'callback' => 'get_customer'
));
register_rest_route('frontend', '/customer/', array(
'methods' => 'POST',
'callback' => 'create_user_and_login'
));
These are my functions:
function get_customer()
{
return get_current_user_id();
}
function create_user_and_login(){
// dummy data for testing
$credentials = ['user_login' => 'mail#mymail.de', 'user_password' => 'XXXX', 'remember' => true];
// create a new user/customer via woocommerce
$customerId = wc_create_new_customer($credentials['user_login'], $credentials['user_login'], $credentials['user_password']);
if(is_a($customerId,'WP_Error')) {
return $customerId;
}
// get the user & log in
$user = get_user_by( 'id', $customerId );
if( $user ) {
wp_set_current_user( $customerId);
wp_set_auth_cookie( $customerId );
}
// create new nonce and return it
$my_nonce = wp_create_nonce('wp_rest');
return $my_nonce;
}
If I now run a POST to /customer which triggers create_user_and_login(), the newly created nonce is returned in the ajax response. Then I use the returned nonce to run my next request, a GET to /customer?_wpnonce=MY-NONCE, but I get the error:
{
"code": "rest_cookie_invalid_nonce",
"message": "Cookie nonce is invalid",
"data": {
"status": 403
}
}
I checked the nonce documentation but I could not find a solution for my problem. Could it be that the sessions are out of sync? So that the nonce is created on the wrong session or wp_set_auth_cookie and wp_set_current_user are not called correctly? Or do I have to use the wp_localize_script function? This will get problematic, as I want to have the ReactJS and the Wordpress backend separated.
I got two cookies after the POST, a wordpress cookie and a wordpress_logged_in cookie.
What am I missing?
Check this answer
It seems that when you call $my_nonce = wp_create_nonce('wp_rest'); the nonce is created with the old session cookie, even when you call wp_set_auth_cookie and wp_set_current_user. But in the next request the session is updated, meaning that the nonce is wrong.
As in the answer, add the following hook (functions.php for example) to force an update of the cookie:
function my_update_cookie( $logged_in_cookie ){
$_COOKIE[LOGGED_IN_COOKIE] = $logged_in_cookie;
}
add_action( 'set_logged_in_cookie', 'my_update_cookie' );

Facebook Login + Drupal 8 custom module. POST variable not being allowed/detected in db_select

I have created a custom module in Drupal 8 that allows a user to authenticate using facebook login. Their access token is checked against one stored in the database and if it matches authenticates the user and if it doesn't then redirects them to a page that allows them to link their Facebook account to a Drupal user.
The button for login is:
<button id="login_fb" onclick="logIt()">Log in with Facebook</button>
The "logit" function with the ajax request to the Drupal controller is:
function logIt()
{
FB.login(function(response) {
if (response.authResponse) {
if(response.authResponse.accessToken)
{
var request = $.ajax({
url: "/user/token",
method: "POST",
data: { access_token : response.authResponse.accessToken},
dataType: "json"
});
request.done(function( msg ) {
window.location.replace(msg['redirect_url']);
});
request.fail(function( jqXHR, textStatus ) {
alert( "Request failed: " + textStatus );
});
}
}
}
And the controller code that handles this ajax call is:
public function token() {
$fb_token = $_POST['access_token'];
$query = db_select('user__field_fb_token', 'u');
$query
->fields('u')
->condition('u.field_fb_token_value', $fb_token,'=');
$res = $query->execute();
$res->allowRowCount = TRUE;
$count = $res->rowCount();
//See if anybody has this access token
if($count > 0)
{
$user = $res->fetchAssoc();
//TODO: Refresh access token and update
$login_id = $user['entity_id'];
//Redirect the user to topics
user_login_finalize(user_load($login_id));
$response_arr = array("status" => "authorised","redirect_url" => "/topics");
}
else
{
$_SESSION['access_token'] = $fb_token;
$response_arr = array("status" => "unauthorised","redirect_url" => "/user/auth","token" => $fb_token);
}
$response = new Response();
$response->setContent(json_encode($response_arr));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
The weird thing is that the db_select query always returns 0 and therefore does not authenticate the user account that has this token. However replacing
$fb_token = $_POST['access_token'];
with
$fb_token = '** hard coded access token **';
yields the correct result. I have checked that the post variable being passed in and it is present (that's why I pass it back with the unauthorised response to check that it's not blank).
I think it may have something to do with the async nature of FB.Login method but not sure.
Any help on this matter would be greatly appreciated!

Is the contacts API dead?

Does the contacts API still work for anyone? A while back I started getting 403 errors from the API. I run my backup script once a week. Every user that I can't back up, I retry every hour until the next week. Over the span of the week I will end up with a couple of contacts entries, but not a significant amount. This leads me to believe that my code still works since I get some contacts. Anyone have any insight?
Note: I also use the same code/framework to backup Google Drive and Google Calendars for my organization and have not had any issues.
function retrieveAllUserContacts($user)
{
$nextLink = "https://www.google.com/m8/feeds/contacts/$user/full";
$params = array('xoauth_requestor_id' => $user);
while($nextLink != '')
{
$header = array('GData-Version: 3.0');
$result = sendOAuthRequest('GET', $nextLink, $params, $header);
$params = array('xoauth_requestor_id' => $user);
$nextLink = '';
libxml_use_internal_errors(true);
$xmlObj = simplexml_load_string($result);
if($xmlObj === false)
{
echo "adding $user to retry list. Result : " . print_r($result, true) . "\n";
addUserToRetryList($user);
exit(1);
}
foreach($xmlObj->link as $link)
{
if($link['rel'] == 'next')
{
$nextLink = $link['href'];
}
if($nextLink != '')
{
$urlSplit = explode('?', $nextLink);
$nextLink = $urlSplit[0];
$urlParams = explode('&', $urlSplit[1]);
foreach($urlParams as $urlParam)
{
$urlParamSplit = explode('=', $urlParam);
$params[$urlParamSplit[0]] = $urlParamSplit[1];
}
break;
}
}
foreach($xmlObj->entry as $entry)
{//get contacts
...
}
function sendOAuthRequest($httpMethod, $url, $parameters, $header=array())
{
global $CONSUMER_KEY;
global $CONSUMER_SECRET;
$consumer = new OAuthConsumer($CONSUMER_KEY, $CONSUMER_SECRET, NULL);
$request = OAuthRequest::from_consumer_and_token($consumer, NULL, $httpMethod, $url, $parameters);
// Sign the constructed OAuth request using HMAC-SHA1
$request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
// Make signed OAuth request to the Contacts API server
if(count($parameters))
{
if(strpos($url, '?') === false)
{
$url .= '?' . implode_assoc('=', '&', $parameters);
}
else
{
$url .= '&' . implode_assoc('=', '&', $parameters);
}
}
$header[] = $request->to_header();
return send_request($request->get_normalized_http_method(), $url, $header);
}
Here is the OAuth Class code : http://pastebin.com/hH4SM9nn I can say that it works for Google Drive and Google Calendar APIs and also that this code worked for over a year without issue.
A number of problems could be causing this. Since your question isn't specific and gives no code sample, here are some of those potential problems:
You have not moved to HTTPS as opposed to HTTP
your GET request specifies a "default" user, where the authority is not always given
You are trying to get too many contacts
There are also issues with authorisation and permissions as of late, one "fix" as such is documented in this StackOverflow answer. It concerns adding not only a google account, but the gmail address associated with that account to the analytics service, via this link.

Resources