I want to store some information in the local browser cookie. After hours looking for a nice tutorial, I managed to store some data in a non-session cookie:
controller - indexAction()
$cookieGuest = array(
'name' => 'mycookie',
'value' => 'testval',
'path' => $this->generateUrl('my_route'),
'time' => time() + 3600 * 24 * 7
);
$cookie = new Cookie($cookieGuest['name'], $cookieGuest['value'], $cookieGuest['time'], $cookieGuest['path']);
$response = new Response();
$response->headers->setCookie($cookie);
$response->send();
I wonder if this is the correct way. Furthermore I tried several ways to read the cookie with the HttpFoundation Component, but without success. Is there another way than accessing the cookie via $_COOKIE['mycookie'] ?
Here is where I try to read the cookie
controller - cookieAction()
public function cookieAction($_locale, $branch, $page)
{
$response = new Response();
$cookies = $response->headers->getCookies();
var_dump($cookies);
// TODO: Get params for indexAction from cookie if available
return $this->indexAction($_locale, $branch, $page);
}
This is the correct way of setting cookie.
To read cookie already written in the browser do:
$request->cookies->get('myCookie');
But after I created cookie in the $response object:
$cookie = new Cookie('myCookie', 'contentOfMyCookie');
$response = new Response();
$response->headers->setCookie($cookie);
I call this method:
$response->headers->getCookies();
I get an array of cookies, which are to be written in the browser - not those already existing there.
Figuratively, between $request and $response there is a time of executing controller's code.
Besides, in a twig template you can use
{{ app.request.cookies.get('myCookie') }}
you thus get value of the cookie already written in the browser, not that from the $response object! Newly created cookie from the browser you can read only after having reloaded page (ajax doesn't need to reload whole page).
To sum it up, you can read cookies using $request object, and create them with $response object. (Obviously, for some reasons, you can also read $response object cookies - but these are rather rare situations).
$response->headers->getCookies();
should return an array of cookies look in ResponseHeaderBag class for more information about that function
this can be useful for someone trying to make cookies in symfony2 :
use Symfony\Component\HttpFoundation\Cookie;
Example how to use Cookies and Session:
<?php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
class DefaultController extends Controller
{
public function indexAction()
{
// Set session value
$session = $this->getRequest()->getSession();
$session->set('test', 1);
// Get session value
$value = $session->get('test');
// Set cookie value
$response = new Response();
$cookie = new Cookie('test', 1, time()+3600);
$response->headers->setCookie($cookie);
// Get cookie value
$this->getRequest()->cookies->get('test');
}
}
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\Response;
// set current active tab in cookie
$cookie = new Cookie('myProfileActiveTab', 'myaddress', strtotime('now + 60 minutes'));
$response = new Response();
$response->headers->setCookie($cookie);
$response->send();
// get current active tab from cookies
$cookies = $request->cookies;
if ($cookies->has('myProfileActiveTab')) {
$activetab = $cookies->get('myProfileActiveTab');
}
More interesting cookies information links (http_fundation component for symfony2):
Symfony2 http_fundation component
Symfony2 http_fundation api
Symfony2 http_fundation component (spanish)
Related
I am passing a cookie in the middleware between requests using
$cookie = Cookie::make('key', 'some-key, 10);
$next = $next($request);
$next->withCookie($cookie);
But am having problem removing the cookie from the $request after I retrieve its value. I can't find any command or helper in the docs to achieve this.
You cannot enforce all clients to delete a cookie. What you can do is set the cookie value to an empty string and set a short expiry time.
As i am either too dump to find the proper answer or it is simply not out there ... how the hek i replace the "outdated" WebRequest properly with the HttpClient "replacement"?
In the WebRequest i tendet to serialize & analyze the actual cookie as the webpage returns a partial JSON cookie ... however ... i still did not found a way to get a proper CookieContainer (or whatever form of cookie) from the frking HttpClient ... also ... every google request leads me to 20000000 years old answers or outdated documents (+ some upToDate docs which all just refer to "GET" requests without any cookies involved -.-*))
would be kindfull if somebody could lead me to the correct path ...
thx
greets
X39
Windows.Web.Http.HttpClient client = new Windows.Web.Http.HttpClient();
client.DefaultRequestHeaders.UserAgent.TryParseAdd(app.Settings.UserAgent);
var response = await client.PostAsync(new Uri(app.Settings.Pr0grammUrl.Api + "user/login"), new Windows.Web.Http.HttpStringContent(postDataBuilder.ToString()));
By default, HttpClient handles cookies by itself through the default HttpBaseProtocolFilter. You can get cookies associated with a URI through GetCookies method of the HttpCookieManager class:
Gets an HttpCookieCollection that contains the HttpCookie instances
that are associated with a specific URI.
using (var protocolFilter = new HttpBaseProtocolFilter()) {
var cookieManager = protocolFilter.CookieManager;
var cookies = cookieManager.GetCookies(uri);
foreach (var cookie in cookies) {
// Here is each cookie
}
}
You should also be able to set/get cookies through HTTP request and response headers. To disallow HttpClient from handling cookies by itself, create an instance of HttpBaseProtocolFilter and set the CookieUsageBehavior to HttpCookieUsageBehavior.NoCookies:
NoCookies: Do not handle cookies automatically.
// Create http filter
httpFilter = new HttpBaseProtocolFilter();
httpFilter.CookieUsageBehavior = HttpCookieUsageBehavior.NoCookies;
// Create http client
httpClient = new HttpClient(httpFilter);
// Handle cookies through HTTP headers
I want to use facebook graph api to get the event details of a specific page.But I keep getting a blank page back.
<?php
error_reporting(E_ALL);
require 'vendor/autoload.php';
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
class HomeController extends BaseController {
public function index()
{
FacebookSession::setDefaultApplication('APP_ID', 'APP_SECRET');
$session = FacebookSession::newAppSession();
/* make the API call */
$request = new FacebookRequest(
$session,
'GET',
'/1531904510362357/'
);
$response = $request->execute();
$graphObject = $response->getGraphObject();
dd($graphObject);
}
$session should = new FacebookSession('accesstoken')
Another thing I've learned is that the new api (v2.0+) is very very strict on what is displayed. For example, you can no longer open up someones feed that doesn't also have an access token to your application.
I would go back and read on the permissions and make sure that the correct permissions are set and validated for your application.
In my javascript I have a click event that triggers an ajax call to the php page where I send my notification from. I chose to do it this way because the documentation advises against using your app secret in any client side code, and the notifications parameters requires an access token that you can only get using the app secret.
The problem I'm having is that even though I'm logged in, $facebook->getUser() is returning 0 in php, so the api call I make afterwards to send the notification wont work. My user is already logged in via the client side code, so how do I get the message to the php that they're logged in so the notification can be sent.
//JS
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {notify: notify },
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});//closes ajax
//PHP
<?php
require_once(dirname(__FILE__).'/php-sdk/facebook.php') ;
$APPLICATION_ID = '1402xxxxx7';
$APPLICATION_SECRET = 'ce71d6bbxxxxx5f55a';
$fb_app_url = "http://apps.facebook.com/myAPP";
$config = array();
$config['appId'] = $APP_ID;
$config['secret'] = $APP_SECRET;
$config['cookie'] = true;
$facebook = new Facebook($config) or die('Error is here!');
$facebook = new Facebook(array(
'appId' => $APP_ID,
'secret' => $APP_SECRET,
'fileUpload' => true
));
$notify = $_REQUEST['notify'];
$userid = $facebook->getUser();
/*IF WE HAVE A LOGGED IN USER AND THE 'NOTIFY' REQUEST VALUE, THEN SEND THE NOTIFICATION.
BUT MY USER ID IS 0. HOW DO I GET PHP TO RECOGNIZE ME AS LOGGED IN WITHOUT HAVING TO FORCE MY USER TO LOG IN VIA PHP AFTER THEY'VE ALREADY LOGGED IN CLIENT SIDE?*/
if($userid && $notify){
$token_url ="https://graph.facebook.com/oauth/access_token?" .
"client_id=" . $APP_ID .
"&client_secret=" . $APP_SECRET .
"&grant_type=client_credentials";
$app_token = file_get_contents($token_url);
$app_token = str_replace("access_token=", "", $app_token);
$data = array(
'href'=> 'https://apps.facebook.com/thebringernetwork/',
'access_token'=> $app_token,
'template'=> 'test'
);
$sendnotification = $facebook->api('/1622649653/notifications', 'post', $data);
}else{
//handle error
}
?>
The first thing I noticed is that you define your app id as $APPLICATION_ID but use it as $APP_ID (and the same goes for your app secret). But since you didn't mention any errors and $facebook->getUser(); executes I'm guessing this is just a bad copy-paste.
Now for the sake of answering this question I'm going to presume that you are using the latest versions of both JS and PHP SDKs. These use oauth 2.0 and change the way you pass the login information from JS to PHP.
According to Facebook Developer Blog removing $config['cookie'] = true; and setting oauth to true in your JS configuration should work. Just make sure to refresh the site after the login.
The solution I've found in my own project is to disable cookies altogether and simply pass the access token to my PHP script.
In your JS call your PHP script like this (make sure to call this after the JS login!):
$.ajax({
url : "http://xxxxxo/bn/notification.php",
type : 'POST',
data: {
notify: notify,
token: FB.getAuthResponse()['accessToken'] // add your access token
},
success : function (result) {
console.log(result);
},
error : function () {
alert("error sending notification");
}
});
And in your PHP script add this after creating the FB object.
$facebook->setAccessToken($_POST['token']); // set the users access token
Doing things this way will also get rid of any need to refresh the website after the login.
Yes, this is a common problem when using the PHP SDK in combination with AJAX:
When you make an AJAX request, the PHP SDK deletes the cookies where the authorization information are stored, and then the next call to getUser will just return 0, because this method tries to find the current user id in those cookies – apparently there is something in the OAuth 2.0 spec that demands this behavior to prevent some sort of click-jacking attack.
But the info will still be stored in the session, so you can read the user id (and the user access token, should you need it) from there:
$user_id = $_SESSION['fb_YourAppIdHere_user_id'];
$user_access_token = $_SESSION['fb_YourAppIdHere_access_token'];
Replace YourAppIdHere with your app id (so it becomes fb_1234567890_user_id resp. fb_1234567890_access_token) to get the correct names of those session keys.
I am working in a Windows Phone 8 PCL project. I am using a 3rd party REST API and I need to use a few HttpOnly cookies originated by the API. It seems like getting/accessing the HttpOnly cookies from HttpClientHandler's CookieContainer is not possible unless you use reflection or some other backdoor.
I need to get these cookies and send them in subsequent requests otherwise I am not going to be able to work with this API - how can I accomplish this? Here is what my current request code looks like:
Thanks in advance.
//Some request
HttpRequestMessage request = new HttpRequestMessage();
HttpClientHandler handler = new HttpClientHandler();
//Cycle through the cookie store and add existing cookies for the susbsequent request
foreach (KeyValuePair<string, Cookie> cookie in CookieManager.Instance.Cookies)
{
handler.CookieContainer.Add(request.RequestUri, new Cookie(cookie.Value.Name, cookie.Value.Value));
}
//Send the request asynchronously
HttpResponseMessage response = await httpClient.SendAsync(request);
response.EnsureSuccessStatusCode();
//Parse all returned cookies and place in cookie store
foreach (Cookie clientcookie in handler.CookieContainer.GetCookies(request.RequestUri))
{
if (!CookieManager.Instance.Cookies.ContainsKey(clientcookie.Name))
CookieManager.Instance.Cookies.Add(clientcookie.Name, clientcookie);
else
CookieManager.Instance.Cookies[clientcookie.Name] = clientcookie;
}
HttpClient httpClient = new HttpClient(handler);
The HttpOnly cookie is inside the CookieContainer, it's only that is not exposed. If you set the same instance of that CookieContainer to the next request it will set the hidden cookie there (as long as the request is made to the same site the cookie specifies).
That solution will work until you need to serialize and deserialize the CookieContainer because you are restoring state. Once you do that you lose the HttpOnly cookies hidden inside the CookieContainer. So, a more permanent solution would be using Sockets directly for that request, read the raw request as a string, extract the cookie and set it to the next requests. Here's the code for using Sockets in Windows Phone 8:
public async Task<string> Send(Uri requestUri, string request)
{
var socket = new StreamSocket();
var hostname = new HostName(requestUri.Host);
await socket.ConnectAsync(hostname, requestUri.Port.ToString());
var writer = new DataWriter(socket.OutputStream);
writer.WriteString(request);
await writer.StoreAsync();
var reader = new DataReader(socket.InputStream)
{
InputStreamOptions = InputStreamOptions.Partial
};
var count = await reader.LoadAsync(512);
if (count > 0)
return reader.ReadString(count);
return null;
}
There is also a second possibility - to manually go through response headers, grab and then parse Set-Cookie headers using a bunch of custom code.
It looks something like that, when you are going to match and save a single PHPSESSID cookie (assume LatestResponse is your HttpResponseMessage containing website response):
if (LatestResponse.Headers.ToString().IndexOf("Set-Cookie:") != -1) try
{
string sid = LatestResponse.Headers.ToString();
sid = sid.Substring(sid.IndexOf("Set-Cookie:"), 128);
if (sid.IndexOf("PHPSESSID=") != -1)
{
settings.Values["SessionID"] = SessionID = sid.Substring(sid.IndexOf("PHPSESSID=") + 10, sid.IndexOf(';') - sid.IndexOf("PHPSESSID=") - 10);
handler.CookieContainer.Add(new Uri("http://example.com", UriKind.Absolute), new System.Net.Cookie("PHPSESSID", SessionID));
}
} catch (Exception e) {
// your exception handling
}
Note this code inserts the cookie to CookieContainer for that object's life unless manually deleted. If you want to include it in a new object, just pull the right setting value and add it to your new container.