I use the following code to perform sub-request in HMVC structure:
A request to "page1" will make a sub-request to "page2" by the following code:
$request = Request::factory('/page2')
->method(Request::POST)
->post($postData)
->execute();
The execution in "page2" will add / change the value of a cookies item by
setcookie('new_var', $newValue);
Now I need to capture the new value of the cookie "new_var" in "Page1". So how can I do that?
PS: Due to some limitations, I have to set the 'new_var' in cookie, so putting it to session is not an answer.
==========update =============
As suggested by zerkms, I did something like this:
$response = Request::factory('/page2')
->method(Request::POST)
->post($postData);
//before
error_log(print_r($response->cookie(), TRUE));
$response->execute();
//after
error_log(print_r($response->cookie(), TRUE));
the result of the "before" and "after" log entries are both empty array. :(
In kohana you'd better used Response::cookie() method.
In this case you can use this method for both retrieving and setting cookies (even in the same request)
Related
In a Laravel 6x project I'm working on I'm setting a cookie with:
Cookie::queue('remember_me', json_encode(['uid' => $user->id, 'token' => $token]),2628000);
I'm reading the cookie and decrypting it with:
$cookies = Crypt::decrypt(Cookie::get('remember_me'),false);
This works well, except that the value of $cookies has an extra pre-pended string and a | delimiter in it:
e80cd502fec2a621b624ead8eb1cc91a2e94846b|{"uid":872,"token":"l1214065120208k"}
I can work with that obviously to get what I need but I have been unable to find anything on why that string and | are being prepended to the cookie. Any explanation or documentation link?
I did find another thread here with a similar question but no answer:
How to decrypt cookies in Laravel 8
I also found a thread suggesting that Laravel 8 adds the session_id to the cookie string. Is that what I'm seeing here?
Thanks,
Michael
This value looks to be an HMAC-SHA1 of the cookie name with v2 appended to the end.
This logic is implemented in the CookieValuePrefix class in Laravel and the code looks like so:
public static function create($cookieName, $key)
{
return hash_hmac('sha1', $cookieName.'v2', $key).'|';
}
This is used in the EncryptCookies middleware when encrypting and decrypting accordingly. The relevant source code is:
// in decrypt() function
$hasValidPrefix = strpos($value, CookieValuePrefix::create($key, $this->encrypter->getKey())) === 0;
$request->cookies->set(
$key, $hasValidPrefix ? CookieValuePrefix::remove($value) : null
);
// in encrypt() function
$this->encrypter->encrypt(
CookieValuePrefix::create($cookie->getName(), $this->encrypter->getKey()).$cookie->getValue(),
static::serialized($cookie->getName())
)
I put this logic into a CyberChef page here to test it out with some local cookies I had and verify the output matches and it did. If you go there and plug in your app key (preferable a disposable one) you should see it output the hash value you have in your question.
Using AngleSharp v 0.9.9, I'm loading a page with OpenAsync which sets a bunch of cookies, something like:
var configuration = Configuration.Default.WithHttpClientRequester().WithCookies();
var currentContext = BrowsingContext.New(configuration);
// ....
var doc = context.OpenAsync(url, token);
This works fine and I can see the cookies have been set. For example, I can do this:
var cookieProvider = currentContext.Configuration.Services.OfType<ICookieProvider>().First() as MemoryCookieProvider;
And examine it in the debugger and see the cookies in there (for domain=.share.state.nm.us)
Then I need to submit a post:
var request = new DocumentRequest(postUrl);
request.Method = HttpMethod.Post;
request.Headers["Content-Type"] = "application/x-www-form-urlencoded";
request.Headers["User-Agent"] = userAgent;
//...
Which eventually gets submitted:
var download = loader.DownloadAsync(request);
And I can see (using Fiddler) that it's submitting the cookies from the cookieProvider.
However, I need to add a cookie (and possible change the value in another) and no matter what I try, it doesn't seem to include it. For example, I do this:
cookieProvider.Container.Add(new System.Net.Cookie()
{
Domain = ".share.state.nm.us",
Name = "psback",
Value = "somevalue",
Path = "/"
});
And again I can examine the cookieProvider in the debugger and see the cookie I set. But when I actually submit the request and look in fiddler, the new cookie isn't included.
This seems like it should be really simple, what is the correct way to set a new cookie and have it included in subsequent requests?
I think there are two potential ways to solve this.
either use document.Cookie for setting a new cookie (would require an active document that already is at the desired domain) or
Use a Filter for getting / manipulating the request before its send. This let's you really just change the used cookie container before actually submitting.
The Filter is set in the DefaultLoader configuration. See https://github.com/AngleSharp/AngleSharp/blob/master/src/AngleSharp/ConfigurationExtensions.cs#L152.
I'm trying to use a pre-request script to build out a request object based on data pulled from a CSV file. The problem is that the request seems to be set in stone prior to the pre-request script being run. That would seem to make this a mid-request script almost rather than a pre-request.
My code is as follows:
if(ipList === undefined) ipList = "1.2.3.4,2.3.4.5,123.234.345.465";
let ips = ipList.split(',');
let queryArray = [];
for( i=0; i<ips.length; i++){
queryArray.push({ "key": "ip", "value": ips[i] });
}
console.log(queryArray);
pm.request.url.query = queryArray;
console.log(pm.request);
When I hardcode a url query variable in the request to equal 4.3.2.1, the pm.response.url object like this:
pm.request.url.query[0] = {key:"ip", value:"4.3.2.1"}
Note that the url.query[0] part of the object matches the parameter in the actual get request.
When I change the value of pm.request.url.query to equal the new query array, however as you can see here, the query array is set correctly, but the parameters are not appended to the request URL.
So unless I'm doing something wrong, it appears that the request is immutable even to the pre-request scripts.
So my question is this:
Is there a way to modify the url params of a request prior to making the request?
BTW: I know that is might seem odd to have multiple params with the same key in a query, but that's the way this API works and hard coding multiple ip addresses in the query works just fine.
You could just assign a new value to pm.request.url.
Here I had some query params already in the URL, which I had to edit:
const urlSplit = request.url.split('?');
const paramsString = urlSplit[1]; // the second part actually represents the query string we need to modify
const eachParamArray = paramsString.split('&');
let params = {};
eachParamArray.forEach((param) => {
const key = param.split('=')[0];
const value = param.split('=')[1];
Object.assign(params, {[key]: value});
});
params.bla = params.bla + 'foobar';
newQueryString = Object.keys(params).map(key => key + '=' + params[key]).join('&');
pm.request.url = urlSplit[0] + '?' + newQueryString;
In the end, I just constructed a new URL, using the first part of the previous one & the query string with the edited bla parameter.
This seemed to work for me--it didn't change what the UI shows the query string is, but it changed what the actual request was (looking at the console log)
pm.request.url.addQueryParams(["a=1", "b=2"])
pm.request.url.query.remove("b")
I have some parameters called "script_loginAs" etc... named such that people on my team know the parameter is evaluated and not sent.
I debug my API using Xdebug and PHPStorm's debugging features. For this to work, the client needs a cookie named XDEBUG_SESSION.
When using Postman, I used to use a Chrome extension to add this cookie, and Postman's cookie interception feature to get this to work in Postman (since it's a sandboxed app).
However, I cannot create cookies in Paw. So, as a workaround, I modified the API response cookie to have the key as XDEBUG_SESSION and value as PHPSTORM, and debugging worked fine. However, this is not ideal as I would also like to set the expiry date to something far in the future (which I can't in Paw).
So, my questions are:
Is there a way to add custom cookies in Paw?
If not, is there a way to to edit the expiry date for an existing cookie (considering that name, value, domain and path are editable)?
Are there any other alternatives to achieve my objective?
I just managed to achieve this exact thing to debug my APIs with Paw (2.1.1).
You just have to Add a Header with the name Cookie and a value of Cookies picked from the dropdown that will appear. You then have to insert a Cookie named XDEBUG_SESSION with a value of PHPSTORM inside the Cookies value of the header just created.
To be more clear, you can see it in the screenshot below:
I messed around with it to see if I could create an extension. I wasn't able to, and the below does not work but thought I'd share in case anyone knows the missing pieces.
First off, there is no extension category (generator, dynamic value, importer) that this functionality falls into. I tried to make use of the dynamic value category but was unsuccessful:
CookieInjector = function(key, value) {
this.key = "XDEBUG_SESSION";
this.value = "PHPSTORM";
this.evaluate = function () {
var f = function (x,y) {
document.cookie=this.key+"="+this.value;
return true;
}
return f(this.key, this.value);
}
// Title function: takes no params, should return the string to display as
// the Dynamic Value title
this.title = function() {
return "Cookie"
}
// Text function: takes no params, should return the string to display as
// the Dynamic Value text
this.text = function() {
return this.key+"="+this.value;
}
}
// Extension Identifier (as a reverse domain name)
CookieInjector.identifier = "com.luckymarmot.PawExtensions.CookieInjector";
// Extension Name
CookieInjector.title = "Inject Cookie Into Cookie Jar";
// Dynamic Value Inputs
CookieInjector.inputs = [
DynamicValueInput("key", "Key", "String"),
DynamicValueInput("value", "Value", "String")
]
// Register this new Extension
registerDynamicValueClass(CookieInjector);
The main thing stopping this from working is I'm not sure how the request is built in PAW and not sure how to attach the cookie. I've looked through the documentation here: https://luckymarmot.com/paw/doc/Extensions/Reference/Reference, and can't find what I need.
I've found a few questions and pages dealing with cookies in Symfony2 but there doesn't seem to be any clear consensus on exactly how this is supposed to work. I can, of course, just fall back to using PHP's native setcookie function but I feel that it should be an easy thing to do with Symfony2 as well.
I have an action in my controller from which I simply want to return a view with a cookie attached. Thus far I have seem examples basically like this:
use Symfony\Compentnt\HttpFoundation\Response;
public function indexAction() {
$response = new Response();
$response->headers->setCookie(new Cookie('name', 'value', 0, '/');
$response->send();
}
The problem with this is that it sends the response... and doesn't render the view. If I set the cookie without sending the headers the view is rendered but the header (cookie) is not sent.
Poking around I found the sendHeaders() method in the Response object so I'm now manually calling that in my action before returning and that seems to work:
public function indexAction() {
...
$response->sendHeaders();
return array('variables' => 'values');
}
But is this really the expected pattern to use? In previous versions of symfony I could set the headers in my controller and expect the view controller to handle sending whatever I had sent. It seems now that I must manually send them from the action to get it to work, meaning I have to call this from any action that I set headers in. Is this the case or is there something that I'm missing that's so obvious that no one has bothered to even mention it in any of the documentation?
I think you're on the right lines with:
$response->headers->setCookie(new Cookie('name', 'value', 0, '/'));
If you're trying to render a template then check out the docs here:
Symfony2 Templating Service
If you look at the line:
return $this->render('AcmeArticleBundle:Article:index.html.twig');
basically the render method is returning a response (which the controller then returns) which has the content of the twig template, all you have to do is intercept this:
$response = $this->render('AcmeArticleBundle:Article:index.html.twig');
$response->headers->setCookie(new Cookie('name', 'value', 0, '/'));
return $response;
I think that's it anyway...