Encrypted Cookies in Slim Framework v3 - php

I am writing and application in Slim Framework v3.1. I am a lot confused on how to correctly set and get the cookies using Slim's methods.
I need your help in understanding what is the right way to read and write cookies with encryption enabled.
I also need to know how to enable encryption and decryption for the same.
Currently my $app is initialised this way -
$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);
My settings.php looks like below -
return [
'settings' => [
'displayErrorDetails' => true, // set to false in production
'addContentLengthHeader' => false, // Allow the web server to send the content-length header
// Renderer settings
'renderer' => [
'template_path' => __DIR__ . '/../templates/',
],
// Cookies Encryption
'cookies.encrypt' => true,
'cookies.secret_key' => '53cr3t',
'cookies.cipher' => OPENSSL_CIPHER_AES_256_CBC,
'cookies.cipher_mode' => MCRYPT_MODE_CBC,
],
];

Related

Guzzle always convert all my headers to lowercase

I have a script that uses guzzle to make an API call. The api server checks for headers and it is case sensitive.
Below is an example code of mine
<?php
$headers = [
'set_headers' => [
'Connection' => 'Keep-Alive',
'Accept-Encoding' => ‘gzip’,
'Accept-Language' => ‘en_US’,
'US-Token' => '1f23a-d234s-3s45d-452g',
'AToken' => 'XXXX'
],
];
// Build HTTP request object.
$request = \GuzzleHttp\Psr7\Request( // Throws (they didn't document that properly).
'POST',
'htps://api.website.com/',
$headers,
bodystream() //StreamInterface
);
// Default request options (immutable after client creation).
$_guzzleClient = new \GuzzleHttp\Client([
'handler' => $stack, // Our middleware is now injected.
'allow_redirects' => [
'max' => 8, // Allow up to eight redirects (that's plenty).
],
'connect_timeout' => 30.0, // Give up trying to connect after 30s.
'decode_content' => true, // Decode gzip/deflate/etc HTTP responses.
'timeout' => 240.0, // Maximum per-request time (seconds).
// Tells Guzzle to stop throwing exceptions on non-"2xx" HTTP codes,
// thus ensuring that it only triggers exceptions on socket errors!
// We'll instead MANUALLY be throwing on certain other HTTP codes.
'http_errors' => false,
]);
// Add critically important options for authenticating the request.
$guzzleOptions = [
'cookies' => ($_cookieJar instanceof CookieJar ? $_cookieJar : false),
'verify' => file_exists('/etc/ssl/certs/cacert.pem') ? '/etc/ssl/certs/cacert.pem' : $_verifySSL,
'proxy' => ($_proxy !== null ? $_proxy : null),
'curl' => [
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2, // Make http client work with HTTP 2/0
CURLOPT_SSLVERSION => 1,
CURLOPT_SSL_VERIFYPEER => false
]
];
// Attempt the request. Will throw in case of socket errors!
$response = $_guzzleClient->send($request, $guzzleOptions); ?>
I tested the same request with cURL and it works perfectly. Is there a way I can rectify this in the guzzle php library, thanks in advance.

Slim v4 Creating Log File

So, my issue is that I'm having trouble to make Slim record all its actions inside a file (for example : app.log). I ran across a lot of tutorials and other forum similar to this one but the issue was that they were using the v3 of the Slim Framework.
I saw some post suggesting things like this inside a settings.php :
return [
'settings' => [
'displayErrorDetails' => true, // set to false in production
'addContentLengthHeader' => false, // Allow the web server to send the content-length header
// Renderer settings
'renderer' => [
'template_path' => __DIR__ . '/../templates/',
],
// Monolog settings
'logger' => [
'name' => 'my-app',
'path' => __DIR__ . '/../logs/' . $logDate->format('Y-m-d') . 'app.log',
],
],
];
But the issue with that method is that, well, settings aren't set up this way anymore in v4. So here I am. Stuck. If anybody could give me a hand, it'll help a lot !
To load the settings within a container you have to add a container definition for it.
Example settings file: config/settings.php
return [
// set to false in production
'displayErrorDetails' => true,
// Renderer settings
'renderer' => [
'template_path' => __DIR__ . '/../templates/',
],
// Monolog settings
'logger' => [
'name' => 'my-app',
'path' => __DIR__ . '/../logs/' . date('Y-m-d') . '_app.log',
],
];
Example container entry in config/container.php:
use Psr\Container\ContainerInterface;
// ...
return [
// ...
'settings' => function () {
return require __DIR__ . '/settings.php';
},
// Add more entries here ...
}
To fetch the settings within the container use this:
use Psr\Container\ContainerInterface;
use Psr\Log\LoggerInterface;
// ...
return [
// ...
LoggerInterface::class => function (ContainerInterface $container) {
$settings = $container->get('settings');
$name = $settings['logger']['name'];
$logger = new Logger($name);
// Add logger handler...
return $logger;
},
// ...
}
Tip: For autowiring support it's better to use an collection object instead of an simple "string" as container identifier. Read more

Is there any way to overwrite CONSUMER_KEY and CONSUMER_SECRET

I am using laravel with the thujohn/twitter package.
But i want whenever any use registered they will provide us CONSUMER_KEY and CONSUMER_SECRET and we will use that details to post the tweet,favorites tweet etc.
But in the thujohn/twitter package the CONSUMER_KEY and CONSUMER_SECRET is set one time and that will use for all users and i want to use each register user will use their own consumer details.
Any one know any solution on the same
Looking at the source code you have the reconfigure method:
/**
* Set new config values for the OAuth class like different tokens.
*
* #param Array $config An array containing the values that should be overwritten.
*
* #return void
*/
public function reconfig($config)
{
// The consumer key and secret must always be included when reconfiguring
$config = array_merge($this->parent_config, $config);
parent::reconfigure($config);
return $this;
}
So you can pass an array with the configs you want:
Twitter::reconfigure([
'consumer_key' => '',
'consumer_secret' => '',
'token' => '',
'secret' => '',
]);
This configs will then be passed to the parent which is another library called tmhOAuth here's the code for that:
public function reconfigure($config=array()) {
// default configuration options
$this->config = array_merge(
array(
// leave 'user_agent' blank for default, otherwise set this to
// something that clearly identifies your app
'user_agent' => '',
'host' => 'api.twitter.com',
'method' => 'GET',
'consumer_key' => '',
'consumer_secret' => '',
'token' => '',
'secret' => '',
// OAuth2 bearer token. This should already be URL encoded
'bearer' => '',
// oauth signing variables that are not dynamic
'oauth_version' => '1.0',
'oauth_signature_method' => 'HMAC-SHA1',
// you probably don't want to change any of these curl values
'curl_http_version' => CURL_HTTP_VERSION_1_1,
'curl_connecttimeout' => 30,
'curl_timeout' => 10,
// for security this should always be set to 2.
'curl_ssl_verifyhost' => 2,
// for security this should always be set to true.
'curl_ssl_verifypeer' => true,
// for security this should always be set to true.
'use_ssl' => true,
// you can get the latest cacert.pem from here http://curl.haxx.se/ca/cacert.pem
// if you're getting HTTP 0 responses, check cacert.pem exists and is readable
// without it curl won't be able to create an SSL connection
'curl_cainfo' => __DIR__ . DIRECTORY_SEPARATOR . 'cacert.pem',
'curl_capath' => __DIR__,
// in some cases (very very odd ones) the SSL version must be set manually.
// unless you know why your are changing this, you should leave it as false
// to allow PHP to determine the value for this setting itself.
'curl_sslversion' => false,
'curl_followlocation' => false, // whether to follow redirects or not
// support for proxy servers
'curl_proxy' => false, // really you don't want to use this if you are using streaming
'curl_proxyuserpwd' => false, // format username:password for proxy, if required
'curl_encoding' => '', // leave blank for all supported formats, else use gzip, deflate, identity etc
// streaming API configuration
'is_streaming' => false,
'streaming_eol' => "\r\n",
'streaming_metrics_interval' => 10,
// header or querystring. You should always use header!
// this is just to help me debug other developers implementations
'as_header' => true,
'force_nonce' => false, // used for checking signatures. leave as false for auto
'force_timestamp' => false, // used for checking signatures. leave as false for auto
),
$config
);
}

How to set CURLOPT_PROXY in Guzzle right way?

I am trying to set CURLOPT_PROXY but it doesn't work. Curl is enabled. If I do this by "raw" curl request - everything works.. So? What could be the solution?
$client = new GuzzleHttp\Client();
$res = $client->get('http://www.ipmango.com/api/myip', [
'config' => [
'curl' => [
'CURLOPT_PROXY' => '194.135.220.18:8081',
],
]
]);
echo $res->getBody(); // displays my ip addess, not that what I set.
I spent numerous hours finding out myself that you will also need to set the option CURLOPT_HTTPPROXYTUNNEL to 1. So something like:
<?php
$res = $client->get('http://www.ipmango.com/api/myip', [
'config' => [
'curl' => [
'CURLOPT_PROXY' => '194.135.220.18:8081',
'CURLOPT_HTTPPROXYTUNNEL' => 1,
]
]
]);
GuzzleHttp Client automatically detects if environment variables HTTP_PROXY and HTTPS_PROXY are set.
(see lines 165-175 of \path\to\project\vendor\guzzlehttp\guzzle\src\Client.php)
So set both HTTP_PROXY=http://ip:port and HTTPS_PROXY=https://ip:port as system environment variables. Now restart your command line, and rerun php artisan serve
You may be able to configure authentication for your proxy in the environment variable as well, if it's required
Guzzle docs give info about setting proxy for a single request
$client->request('GET', '/', ['proxy' => 'tcp://localhost:8125']);
http://docs.guzzlephp.org/en/latest/request-options.html#proxy
But you can set it to all requests when initializing client
$client = new Client([
'base_uri' => 'http://doma.in/',
'timeout' => 10.0,
'cookie' => true,
'proxy' => 'tcp://12.34.56.78:3128',
]);

Persisting Sessions in Slim

I'm working on a web app using Slim, but I'm facing an issue with setting and persisting sessions.
Here is my index.php. I am trying to set a csrfToken key in the $_SESSION array, so that every request that is made through the app checks if the user has a csrfToken key, if not it will create one.
I'm just confused as to why it isn't persisting because on the next request it's gone. session_start is being called, it's being called automatically by '\Slim\Middleware\SessionCookie'.
Any ideas why this wouldn't be working? And would it be better to place this into middleware or use a hook?
use duncan3dc\Laravel\Blade;
use duncan3dc\Helpers\Env;
# TODO: Bootstrap the app. Move this to a seperate file. Dev only.
R::setup('mysql:host=localhost;dbname=somedb','user','pass');
$app = new \Slim\Slim(array(
'mode' => 'development',
'templates.path' => './views',
'cookies.encrypt' => true,
'cookies.secret_key' => 'mylongsecretkey',
'cookies.cipher' => MCRYPT_RIJNDAEL_256,
'cookies.cipher_mode' => MCRYPT_MODE_CBC
));
$app->add(new \Slim\Middleware\SessionCookie(array(
'expires' => '10 minutes',
'path' => '/',
'domain' => 'site.com',
'secure' => false, # Contact client to discuss using SSL
'httponly' => false,
'name' => '_sus',
'secret' => 'mylongsecretkey', # Do I need this twice?
'cipher' => MCRYPT_RIJNDAEL_256,
'cipher_mode' => MCRYPT_MODE_CBC
)));
# Not persisting ...
if(!isset($_SESSION['csrfToken']))
$_SESSION['csrfToken'] = hash("sha512",mt_rand(0,mt_getrandmax()));
# TODO: Bootstrap these.
require 'routes/index.php';
require 'routes/dashboard.php';
require 'routes/signup.php';
require 'routes/contactus.php';
require 'routes/privacypolicy.php';
require 'routes/testimonials.php';
require 'routes/login.php';
$app->run();
I figured out how to do it after reading more into hooks.
$app->hook('slim.before.router', function() use ($app){
if(!isset($_SESSION['csrfToken']))
$_SESSION['csrfToken'] = hash("sha512",mt_rand(0,mt_getrandmax()));
});

Categories