I don't know anything about agavi and there might be a lot of error in this..
I want to set up a cookie:
$this->getResponse()->setCookie( ID, 'ID=2342&ClickBannerID=634&SubID=&ClickDateTime=' + time(), mixed $lifetime = time() * 2, string $path = '/', string $domain = 'mydomain', bool $secure = null)
I get:
Parse error: syntax error, unexpected T_VARIABLE
it's form: http://www.agavi.org/apidocs/index.html
what am I doing wrong
Usually within Agavi you set cookies on an AgaviView on the AgaviWebResponse object via its setCookie method. The method signature is as follows:
public function setCookie($name, $value, $lifetime = null, $path = null, $domain = null, $secure = null, $httponly = null)
This means, that you can set a simple cookie using the following syntax:
$this->getResponse()->setCookie('cookieName', $cookieValue);
You may use PHP's strtotime function to set an easily readable lifetime for the cookie if you want a cookie that is only valid for a certain amount of time:
$this->getResponse()->setCookie('cookieName', $cookieValue, '+14 days');
As your question states you may want to use the additional parameters (domain etc.) as well. Reading your question it may also be possible, that you want to set multiple cookies instead of one consisting of a string containing ID, ClickBannerId etc., but only you and your application (or your dev) can tell that.
Please note, that you can set the additional parameters per cookie or configure some sane defaults for your application in the app/config/factories.xml file per environment (usually for context _web_) to save on typing in your views:
<response class="AgaviWebResponse">
<ae:parameters name="cookie_httponly">true</ae:parameters>
</response>
The valid parameter names are:
cookie_lifetime (lifetime in seconds)
cookie_path (path on the server the cookie should be available for)
cookie_domain (the domain the cookie is available on)
cookie_secure (set this to true if the cookie should only be available via HTTPS)
cookie_httponly (determine whether the cookie should only be allowed to use via HTTP and not client side scripts)
Please note, that the ae namespace was not necessary in older Agavi versions and thus it may be needed that you use parameter instead of ae:parameter.
To remove a cookie you just call unsetCookie with all the same parameters you used for setting the cookie. To get a cookie value simply call getCookie($name). As cookies are untrusted user provided information usually Agavi requires you to validate all incoming parameters, files, headers and cookies before you can access them in your actions and views. This means, that you may need to validate your cookie prior to accessing its value. You do this via a validate.xml file:
<validator class="string" source="cookie" required="false">
<argument>cookieName</argument>
</validator>
This example is simplified and should not be used in production. Use source _cookie_ and the name of the cookie for the argument and then validate your cookie value according to your rules (format etc.). It may be necessary to write a custom validator if the builtin AgaviValidator classes (like string, regex etc.) are not sufficient, but this is a topic for another day. You may find the Agavi User FAQ somewhat helpful. Sorry for the shameless plug and good luck with your problem at hand. :-)
you mixed function declaration with its run
$this->getResponse()->setCookie( 'your-cookie-id','ID=2342&ClickBannerID=634&SubID=&ClickDateTime=' . time(), time() * 2, '/',
'mydomain', null)
and as OcuS stated in comment - probably hire a PHP developer
Related
I set cookies like this:
$this->Cookie->write('mycookie', $data, TRUE, '30 days');
And I read them like this:
$cookieData = $this->Cookie->read('mycookie');
But for security concerns I read some of the cookies like this:
$cookieRaw= $_COOKIE['CakeCookie']['mycookie'];
And I write this raw cookie to my database. Then I need to read the content of the cookie.
But as you know raw cookie is something like "Q2FrZQ=dsdsaDASDasdasdsa".
So I need to read the content of the cookie.
It seems like CookieComponent:read() uses protected CookieComponent:_decrypt function. I don't want to copy paste the _decrypt() contents. Is there an easier way to read decrypted CakePHP strings ?
I don't see a reason for not using CookieComponent, for your information this component DO encrypt whatever you write. Here is an extract of the documentation
All values in the cookie are encrypted by default. If you want to store the values as plain-text, set the third parameter of the write() method to false. The encryption performed on cookie values is fairly uncomplicated encryption system. It uses Security.salt and a predefined Configure class var Security.cipherSeed to encrypt values. To make your cookies more secure you should change Security.cipherSeed in app/Config/core.php to ensure a better encryption.:
If you need to store the data encrypted, then I'd suggest to encrypt it yourself instead of relying on the cookie component internals.
ie, read the cookie data using the cookie component so that you end up with the decrypted data, then encrypt it with your favorite encryption algorithm (I'd suggest to use Security::rijndael()) and store it in the database, that way you have proper control over the data.
Another option would be to create a custom component that extends the cookie component and makes the decrypting functionality public. However I really don't think that's a good idea, the data in the DB shouldn't be a components concern, this is something that fits way better in the model layer.
If you insist using the mundged cookie data and decrypting it manually, then you'll have to do the same as can be seen in the CookieComponent code. First strip the Q2FrZQ==. from the data, then base64 decode it, afterwards decrypt it according to the method used by the cookie component (Security::cipher() by default, which is btw deprecated), and finally JSON decode it if necessary as in CookieComponent::_explode().
Assuming that only Cake 2.x style cookie data is used, and that the data is expected to be always encrypted, then it could be broken down to this (where the decryption method might need to be adjusted, depending on the cookie component configuration):
$data = substr($data, 8);
$data = base64_decode($data);
$data = Security::cipher($data, Configure::read('Security.salt'));
$first = substr($data, 0, 1);
if ($first === '{' || $first === '[') {
$decoded = json_decode($data, true);
if($decoded !== null) $data = $decoded;
}
However this heavily relies on the cookie component internals and configuration, so again, this is anything but recommended!
I'm using Kohana 3.2, and I want to be able to call another script (unrelated to Kohana, outside of its 'jurisdiction') that returns a application/json response.
When I tried using:
$response = json_decode(Request::factory('/scripts/index.php?id=json')->execute()->body());
It errors out saying there's no route to scripts/index.php. So I tried using Request_Client_External
Request_Client_External::factory()->execute(Request::factory('/scripts/index.php?page=s'))->body();
Gives me Request_Exception [ 0 ]: Error fetching remote /scripts/index.php?page=s [ status 0 ] Could not resolve host: scripts; Host not found. It appears it need a full flagged URL using http/https, but how to avoid the overhead of it doing a real external request?
Doing a
Request::factory(url::site('/scripts/index.php?page=s', 'http'))->execute()
works but is it considered "external"?
The short answer to your question is that the only way to use Request::factory()->execute() to achieve that is to use pass it the full url (with whatever "overhead" that entails, which shouldn't be too much: your server's probably quite good at talking to itself).
Otherwise, ideally you'd put the functionality of scripts into a library and call that from Kohana. However it sounds like that's not an option for you. If you have to leave /scripts/index.php untouched and insist on an 'internal' request, you could use PHP's output buffering, as illustrated below. But there are a bunch of caveats so I wouldn't recommend it: the best way is passing a full url.
// Go one level deeper into output buffering
ob_start();
// Mimic your query string ?id=json (see first caveat below)
$_GET = $_REQUEST = array('id' => 'json');
// Get rid of $_POST and $_FILES
$_POST = $_FILES = array();
// Read the file's contents as $json
include('/scripts/index.php');
$json = ob_get_clean();
$response = json_decode($json);
Some caveats.
Firstly, the code changes $_GLOBALS. You probably don't use these in your Kohana code (you use $this->request->get() like a good HMVCer, right?). But in case you do, you should 'remember' and then restore the values, putting $old_globals = $GLOBALS; etc. before the above code, and $GLOBALS = $old_globals; after.
Sessions: if your /scripts/index.php uses `session_start() this will cause a warning if you've already started a session at this point in Kohana.
Note that all variables set in scripts/index.php will remain set in the context you're in. If you want to avoid possible conflicts with that context, you'd start a new context, i.e. wrap the above into its own function.
Finally, you'd also need to make sure that /scripts/index.php doesn't do anything like Kohana::base_url = 'something_else', or touch any other static attributes, or do something catastrophic using this.
I have a lithium app set up that way, so when
return($data)
is used it either can be used in the lithium view.html.php as
echo $data
or if request header "accept" equals "json/javacript" it would return something like
{
data: { a:'b' }
}
automatically.
Unfortunately in the new app that I made as a test app that flow is not happening (and only HTML is always returned).
After doing a little research it seems like that it is supposed to be done automatically if I uncomment
require __DIR__ . '/bootstrap/media.php';
inside bootstrap.php But that didn't work, I still have HTML returned. I downloaded a recent version of the lithium framework(I downloaded it may be 1 or 2 months ago)
Anybody knows if automatic response with JSON requires some set up or not?
taken from http://dev.lithify.me/lithium/tickets/view/353
which is then taken from the lithium docs
To enable automatic content-type negotiation (i.e. determining the content type of the response based on the value of the HTTP Accept header), set the 'negotiate' flag to true. Otherwise, the response will only be based on the type parameter of the request object (defaulting to 'html' if no type is present in the Request parameters)
http://li3.me/docs/lithium/action/Controller::$_render
If you need more help on how to implement leave a comment.
It is also possible to set type to $this->request->accepts() when calling render().
return $this->render(array('type' => $this->request->accepts()));
For some reason I am unable to read any cookies from my CakePHP app on any page after they have been set, the only thing that is returned is garbled text.
My code is as simple as this:
$this->Cookie->write('Region', 'test');
$reg = $this->Cookie->read('Region');
pr($reg);
I uncomment the $this->Cookie->write() line and all I get back is a bunch of random control characters. I also recently upgraded to CakePHP 1.3 but AFAIK this should not effect cookie like this...
This was working fine until I changed server, this must be the root of my problem.
Update
After probing around further I have discovered this is a known issue with the Suhosin security patch for PHP effecting the rand() and srand() methods, I had configured Suhosin to allow the rand() functions but still it is happening, is there a more effective work around out there?
Try this code which will disable cookie encryption:
$this->Cookie->write('Region', 'test', false);
$reg = $this->Cookie->read('Region');
pr($reg);
The write method has the following params:
write(mixed $key, mixed $value, boolean $encrypt, mixed $expires)
By default all values in the cookie are encrypted by CakePHP. However for security reasons you may wish to look into working with the encryption.
CakePHP encrypts cookies by default.
Is your Security.salt value the same in this new installation?
How about the $key value in your cookie controller setup?
I've got a python/WSGI app which needs to check to see if a user has logged on to a PHP web app. The problem is that the PHP app checks if a user has logged on by comparing a value in the $_SESSION variable to a value in the cookie from the user's browser. I would prefer to avoid changing the behavior of the php app if at all possible.
My questions:
Is there anyway I can access the session variables from within python? Where should I start to look?
Are there any obvious security/performance issues I should be aware of when taking this approach?
yep. session (in default) is a regular file. so all what you need is look over session directory and find file with name of session cookie value. then - you have to implement php-like serialize/unserialize and do whatever you want.
nope
Depends on the PHP app, if it's keeping session data in a database (MySQL maybe) you can just connect to the database and get the data, if it's using native PHP sessions you should look to the session.save_path config setting in php.ini, that's the place where the runtime saves files with the session data.
Once you have the data you can parse it to get it unserialized, take a look at how serialize() and unserialize() work in PHP.
I'm currently in the process of trying to run a python server side by side with an existing Apache/php one. A custom solution I arrived at was to save the $_SESSION as an encrypted cookie, letting the php authentication operate as before, then share a private key between the two servers.
Two issues:
Up to you how to handle session expiry stuff.
I haven't bothered with an Initialization Vector, assuming the time stamp from my expiry stuff is enough. See https://stackoverflow.com/a/12486940/4495503 for why I might be being too security lax...
Anyway, my php encrypted cookie function:
session_start();
$encryptToCookie = function($varToEncode,$cookieName,$privateKey){
$iv = $privateKey;
$pass = $privateKey;
$method = 'aes-128-cbc';
$encryptedString = openssl_encrypt(json_encode($varToEncode), $method, $pass, true, $iv);
setcookie($cookieName,bin2hex($encryptedString));
};
$encryptToCookie($_SESSION,"sessionEncrypted","yohoyohoyohoyoho"); // private key must be 16bit
And my python side decryption:
from subprocess import Popen, PIPE
import binascii
def decrypt(encryptedString,privateKey):
encryptedString = binascii.unhexlify(encryptedString)
pathToOpenSSL = 'C:\pysrc\openssl\openssl.exe' # MODIFY THIS!!
openssl = Popen([pathToOpenSSL,
'enc','-aes-128-cbc','-d',
'-nosalt','-nopad','-K',
privateKey.encode('hex'),
'-iv',
privateKey.encode('hex')],
stdin=PIPE,stdout=PIPE)
decryptedString = openssl.communicate(encryptedString)[0].replace('\x04','')
return decryptedString
decrypt(encryptedString,'yohoyohoyohoyoho')
Hope this is of help to someone, remember all the usual stuff about generating private keys and then being careful with them!