Symfony cookie is deleted after redirection - symfony

I know there was a few topics about this but I get see what I've done wrong.
my function for setting cookie is
public function createCookie($city)
{
$expire = time() + (3600 * 24 * 90);
$cookie = new Cookie('calendar_dev_city', $city, $expire, '/', 'cal.dev', false, false);
$response = new Response();
$response->headers->setCookie($cookie);
$response->sendHeaders();
}
if I dump headers right at the end of this function I can see the cookie is set but after redirection it is gone.

You have to return that Response in a controller action.
<?php
// ...
public function pageAction() {
$response = Response::create();
$cookie = $this->makeCookie();
$response->headers->setCookie($cookie);
$response->setContent('thank you for setting the cookie!');
return $response;
}
private function makeCookie() {
$cookie = new Cookie(/* */);
return $cookie;
}

Related

How to pass variables to a RedirectResponse

I've a variable name $email but I don't know how to send it to dashController.php:
$action = $this->client->auth($username, $password);
if (isset($action->success) && $action->success){
$email = $action->data->email;
$response = new RedirectResponse('/dash');
$cookie = new Cookie('JWT', $action->data->jwt->token, new \DateTime($action->data->jwt->expires_at));
$response->headers->setCookie($cookie);
return $response;
}
in dashController.php
class dashController extends authContainer {
#[Route("/dash", "dashboard")]
public function indexAction(): Response
{
return $this->render('dash.twig', [
'email' => ...
]);
}}
If your class inherit from Symfony AbstractController class, you can use the
redirectToRoute method helper. Your code will be like :
if (isset($action->success) && $action->success){
$email = $action->data->email;
$response = $this->redirectToRoute('dashboard');
$cookie = new Cookie('JWT', $action->data->jwt->token, new \DateTime($action->data->jwt->expires_at));
$response->headers->setCookie($cookie);
return $response;
}

JWT web token does not give back user infos

I have a problem with my API. After my login, I have a token, but unfortunately I can not read the information of my user with this token.
my code to have the token (that works):
/**
* #Rest\View()
* #Rest\Post("/api/createToken")
*/
public function createTokenAction(Request $request)
{
// reception payload
$username = $request->request->get('email');
$password = $request->request->get('password');
$user = $this->getDoctrine()
->getRepository('ApplicationSonataUserBundle:User')
->findOneBy(['email' => $username]);
// check user
if (!$user) {
$response = new JsonResponse('User not found');
$response->setStatusCode(Response::HTTP_NOT_FOUND);
return $response;
}
//check password
$encoder_service = $this->get('security.encoder_factory');
$encoder = $encoder_service->getEncoder($user);
$valid = $encoder->isPasswordValid($user->getPassword(), $password, $user->getSalt());
if (!$valid) {
$response = new JsonResponse('User Password is invalid');
$response->setStatusCode(Response::HTTP_NOT_FOUND);
return $response;
}
// store data inside my token
$token = $this->get('lexik_jwt_authentication.encoder')
->encode([
'id' => $user->getId(),
'email' => $user->getEmail(),
'exp' => time() + 3600 // 1 hour expiration
]);
$view = View::create($token);
$view->setFormat('json');
return $view;
}
then I try to use this code to read the information of my token:
/**
* #Rest\View()
* #Rest\Get("/api/user")
*/
public function getUsersAction(Request $request)
{
$response = $this->get('lexik_jwt_authentication.jwt_manager')->create($this->getUser());
$view = View::create($response);
$view->setFormat('json');
return $view;
}
but nothing does .. I do not understand why .. :/
If someone would have a track to offer me please

symfony test - authenticated doesnt work on new request

Good morning.
Tldr: I think that, I need for Symfony Test Client something similiar to js xhr settings: withcredentals:true.
Symfony 3.1. I have action in rest api controller:
/**
* #Rest\GET("/get-stuff")
* #Rest\View
* #Security("is_granted('IS_AUTHENTICATED_FULLY')")
*/
public function GetStuffAction($userId)
{
// get userId from session
$userId = $this->getUser()->getId();
$em = $this->getDoctrine()->getManager();
$Stuff = $em->getRepository('MyApiBundle:Stuff')->findBy(['user' => $userId]);
return $this->viewGroup($Stuff, ['stuff']);
}
And it does work correct.
Now I want Test, so I have :
class TestCase extends WebTestCase
{
public function testIndex()
{
$this->client = self::createClient();
$this->storage = new MockFileSessionStorage(__dir__.'/../../../../app/cache/test/sessions');
$this->session = new Session($this->storage);
$this->logIn($this->getUser(), new Response());
$this->client->request('GET', '/get-stuff');
$content = $this->client->getResponse()->getContent();
$this->assertEquals({"message":"Full authentication is required to access this resource.","code":0},$content);
}
public function logIn(User $user, Response $response)
{
$this->session->start();
$this->cookie = new Cookie('MOCKSESSID', $this->storage->getId());
$this->cookieJar = new CookieJar();
$this->cookieJar->set($this->cookie);
$this->token = new UsernamePasswordToken($user, 'user', 'main', $user->getRoles());
$this->session->set('_security_main', serialize($this->token));
$this->getSecurityManager()->loginUser(
$this->container->getParameter('fos_user.firewall_name'),
$user,
$response
);
$this->session->save();
}
}
And test for it gives me message: "Full authentication is required to access this resource". After method logIn() I can read session data which are connected with logged user.
How can I make to be logged during this part to not receive message about authentication?:
$this->client->request('GET', '/get-stuff');
$content = $this->client->getResponse()->getContent();
More details:
1. My test class extends WebTestCase.
2. My user is overwritten for FosUserBundle.
I suppose that is something like in javascript:
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
but I don't know what.
Thank you in advance for helping solve my problem!
Ok, I was good way to do this:
public function logIn(User $user) {
$session = $this->session;
$firewallContext = 'secured_area';
$token = new UsernamePasswordToken($user, 'user', 'main', $user->getRoles());
$session->set('_security_'.$firewallContext, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
}

Pretty way to send cookie?

$cookie = new Cookie('my-cookie','cookie');
$response->headers->setCookie($cookie);
$response->send();
This code causes problems in case to use redirect
return $this->redirect($this->generateUrl('my_route');
or use SensioFrameworkExtraBundle
/**
* #Template()
*/
public function showAction()
{
return array('entities' => $entities);
}
By following the API doc, $this->redirect Create a new RedirectResponse object so your prepared response with cookie is not used anymore.
You need to create a new RedirectResponse object, set the cookie and return it.
You can do something like that.
$response = new RedirectResponse();
$cookie = new Cookie('my-cookie','cookie');
$response->headers->setCookie($cookie);
return $response
Same thing for return array([...]) that will create a new Response object too.

Typo error with namespace in costum bundle symfony2

I'm following the tutorial "Easy Way to Transform a Twitter OAuth Library into a Symfony 2 Bundle" tuto
But not working for me, Always I got this error:
"The autoloader expected class "FEB\TwitterBundle\Api\TwitterOAuth" to be defined in file "D:\xampp\htdocs\FEB/src\FEB\TwitterBundle\Api\TwitterOAuth.php". The file was found but the class was not in it, the class name or namespace probably has a typo."
I've spent many days and I canĀ“t find out what happen. I'm sure that is a namespace issue but i'm getting crazy.
My twitterapi.php
namespace FEB\TwitterBundle\Api;
use FEB\TwitterBundle\Api\TwitterOAuth;
class TwitterApi {
protected $apiKey;
protected $apiKeySecret;
protected $apiToken;
protected $apiTokenSecret;
public function __construct($apiKey, $apiKeySecret, $apiToken, $apiTokenSecret){
$this->apiKey = $apiKey;
$this->apiKeySecret = $apiKeySecret;
$this->apiToken = $apiToken;
$this->apiTokenSecret = $apiTokenSecret;
}
public function getapiKey(){
return $this->apiKey;
}
public function getUsers($users, $url = 'users/lookup') {
$connection = new TwitterOAuth($this->apiKey, $this->apiKeySecret, $this->apiToken, $this->apiTokenSecret);
$users = $connection->get($url, array('screen_name' => $users));
return $users;
}
}
Any help, please?
Edit:
My TwitterOAuth.php
<?php
/*
* Abraham Williams (abraham#abrah.am) http://abrah.am
*
* The first PHP Library to support OAuth for Twitter's REST API.
*/
/* Load OAuth lib. You can find it at http://oauth.net */
namespace FEB\TwitterBundle\Api\Meta;
/**
* Twitter OAuth class
*/
class TwitterOAuth {
/* Contains the last HTTP status code returned. */
public $http_code;
/* Contains the last API call. */
public $url;
/* Set up the API root URL. */
public $host = "https://api.twitter.com/1.1/";
/* Set timeout default. */
public $timeout = 30;
/* Set connect timeout. */
public $connecttimeout = 30;
/* Verify SSL Cert. */
public $ssl_verifypeer = FALSE;
/* Respons format. */
public $format = 'json';
/* Decode returned json data. */
public $decode_json = TRUE;
/* Contains the last HTTP headers returned. */
public $http_info;
/* Set the useragnet. */
public $useragent = 'TwitterOAuth v0.2.0-beta2';
/* Immediately retry the API call if the response was not successful. */
//public $retry = TRUE;
/**
* Set API URLS
*/
function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; }
function authenticateURL() { return 'https://api.twitter.com/oauth/authenticate'; }
function authorizeURL() { return 'https://api.twitter.com/oauth/authorize'; }
function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; }
/**
* Debug helpers
*/
function lastStatusCode() { return $this->http_status; }
function lastAPICall() { return $this->last_api_call; }
/**
* construct TwitterOAuth object
*/
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
} else {
$this->token = NULL;
}
}
/**
* Get a request_token from Twitter
*
* #returns a key/value array containing oauth_token and oauth_token_secret
*/
function getRequestToken($oauth_callback) {
$parameters = array();
$parameters['oauth_callback'] = $oauth_callback;
$request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* Get the authorize URL
*
* #returns a string
*/
function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) {
if (is_array($token)) {
$token = $token['oauth_token'];
}
if (empty($sign_in_with_twitter)) {
return $this->authorizeURL() . "?oauth_token={$token}";
} else {
return $this->authenticateURL() . "?oauth_token={$token}";
}
}
/**
* Exchange request token and secret for an access token and
* secret, to sign API calls.
*
* #returns array("oauth_token" => "the-access-token",
* "oauth_token_secret" => "the-access-secret",
* "user_id" => "9436992",
* "screen_name" => "abraham")
*/
function getAccessToken($oauth_verifier) {
$parameters = array();
$parameters['oauth_verifier'] = $oauth_verifier;
$request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* One time exchange of username and password for access token and secret.
*
* #returns array("oauth_token" => "the-access-token",
* "oauth_token_secret" => "the-access-secret",
* "user_id" => "9436992",
* "screen_name" => "abraham",
* "x_auth_expires" => "0")
*/
function getXAuthToken($username, $password) {
$parameters = array();
$parameters['x_auth_username'] = $username;
$parameters['x_auth_password'] = $password;
$parameters['x_auth_mode'] = 'client_auth';
$request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* GET wrapper for oAuthRequest.
*/
function get($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'GET', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* POST wrapper for oAuthRequest.
*/
function post($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'POST', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* DELETE wrapper for oAuthReqeust.
*/
function delete($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'DELETE', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* Format and sign an OAuth / API request
*/
function oAuthRequest($url, $method, $parameters) {
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
$url = "{$this->host}{$url}.{$this->format}";
}
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
switch ($method) {
case 'GET':
return $this->http($request->to_url(), 'GET');
default:
return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata());
}
}
/**
* Make an HTTP request
*
* #return API results
*/
function http($url, $method, $postfields = NULL) {
$this->http_info = array();
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
curl_setopt($ci, CURLOPT_HEADER, FALSE);
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
break;
case 'DELETE':
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($postfields)) {
$url = "{$url}?{$postfields}";
}
}
curl_setopt($ci, CURLOPT_URL, $url);
$response = curl_exec($ci);
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
$this->url = $url;
curl_close ($ci);
return $response;
}
/**
* Get the header info to store.
*/
function getHeader($ch, $header) {
$i = strpos($header, ':');
if (!empty($i)) {
$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
$value = trim(substr($header, $i + 2));
$this->http_header[$key] = $value;
}
return strlen($header);
}
}
Edit2: This is the folder structure
Summing all the comments up, your TwitterOAuth.php has to be like this:
<?php
/*
* Abraham Williams (abraham#abrah.am) http://abrah.am
*
* The first PHP Library to support OAuth for Twitter's REST API.
*/
/* Load OAuth lib. You can find it at http://oauth.net */
//require_once('OAuth.php');
namespace FEB\TwitterBundle\Api;
use FEB\TwitterBundle\Api\Meta\OAuthConsumer;
use FEB\TwitterBundle\Api\Meta\OAuthRequest;
use FEB\TwitterBundle\Api\Meta\OAuthSignatureMethod_HMAC_SHA1;
use FEB\TwitterBundle\Api\Meta\OAuthUtil;
/**
* Twitter OAuth class
*/
class TwitterOAuth {
/* Contains the last HTTP status code returned. */
public $http_code;
/* Contains the last API call. */
public $url;
/* Set up the API root URL. */
public $host = "https://api.twitter.com/1.1/";
/* Set timeout default. */
public $timeout = 30;
/* Set connect timeout. */
public $connecttimeout = 30;
/* Verify SSL Cert. */
public $ssl_verifypeer = FALSE;
/* Respons format. */
public $format = 'json';
/* Decode returned json data. */
public $decode_json = TRUE;
/* Contains the last HTTP headers returned. */
public $http_info;
/* Set the useragnet. */
public $useragent = 'TwitterOAuth v0.2.0-beta2';
/* Immediately retry the API call if the response was not successful. */
//public $retry = TRUE;
/**
* Set API URLS
*/
function accessTokenURL() { return 'https://api.twitter.com/oauth/access_token'; }
function authenticateURL() { return 'https://api.twitter.com/oauth/authenticate'; }
function authorizeURL() { return 'https://api.twitter.com/oauth/authorize'; }
function requestTokenURL() { return 'https://api.twitter.com/oauth/request_token'; }
/**
* Debug helpers
*/
function lastStatusCode() { return $this->http_status; }
function lastAPICall() { return $this->last_api_call; }
/**
* construct TwitterOAuth object
*/
function __construct($consumer_key, $consumer_secret, $oauth_token = NULL, $oauth_token_secret = NULL) {
$this->sha1_method = new OAuthSignatureMethod_HMAC_SHA1();
$this->consumer = new OAuthConsumer($consumer_key, $consumer_secret);
if (!empty($oauth_token) && !empty($oauth_token_secret)) {
$this->token = new OAuthConsumer($oauth_token, $oauth_token_secret);
} else {
$this->token = NULL;
}
}
/**
* Get a request_token from Twitter
*
* #returns a key/value array containing oauth_token and oauth_token_secret
*/
function getRequestToken($oauth_callback) {
$parameters = array();
$parameters['oauth_callback'] = $oauth_callback;
$request = $this->oAuthRequest($this->requestTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* Get the authorize URL
*
* #returns a string
*/
function getAuthorizeURL($token, $sign_in_with_twitter = TRUE) {
if (is_array($token)) {
$token = $token['oauth_token'];
}
if (empty($sign_in_with_twitter)) {
return $this->authorizeURL() . "?oauth_token={$token}";
} else {
return $this->authenticateURL() . "?oauth_token={$token}";
}
}
/**
* Exchange request token and secret for an access token and
* secret, to sign API calls.
*
* #returns array("oauth_token" => "the-access-token",
* "oauth_token_secret" => "the-access-secret",
* "user_id" => "9436992",
* "screen_name" => "abraham")
*/
function getAccessToken($oauth_verifier) {
$parameters = array();
$parameters['oauth_verifier'] = $oauth_verifier;
$request = $this->oAuthRequest($this->accessTokenURL(), 'GET', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* One time exchange of username and password for access token and secret.
*
* #returns array("oauth_token" => "the-access-token",
* "oauth_token_secret" => "the-access-secret",
* "user_id" => "9436992",
* "screen_name" => "abraham",
* "x_auth_expires" => "0")
*/
function getXAuthToken($username, $password) {
$parameters = array();
$parameters['x_auth_username'] = $username;
$parameters['x_auth_password'] = $password;
$parameters['x_auth_mode'] = 'client_auth';
$request = $this->oAuthRequest($this->accessTokenURL(), 'POST', $parameters);
$token = OAuthUtil::parse_parameters($request);
$this->token = new OAuthConsumer($token['oauth_token'], $token['oauth_token_secret']);
return $token;
}
/**
* GET wrapper for oAuthRequest.
*/
function get($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'GET', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* POST wrapper for oAuthRequest.
*/
function post($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'POST', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* DELETE wrapper for oAuthReqeust.
*/
function delete($url, $parameters = array()) {
$response = $this->oAuthRequest($url, 'DELETE', $parameters);
if ($this->format === 'json' && $this->decode_json) {
return json_decode($response);
}
return $response;
}
/**
* Format and sign an OAuth / API request
*/
function oAuthRequest($url, $method, $parameters) {
if (strrpos($url, 'https://') !== 0 && strrpos($url, 'http://') !== 0) {
$url = "{$this->host}{$url}.{$this->format}";
}
$request = OAuthRequest::from_consumer_and_token($this->consumer, $this->token, $method, $url, $parameters);
$request->sign_request($this->sha1_method, $this->consumer, $this->token);
switch ($method) {
case 'GET':
return $this->http($request->to_url(), 'GET');
default:
return $this->http($request->get_normalized_http_url(), $method, $request->to_postdata());
}
}
/**
* Make an HTTP request
*
* #return API results
*/
function http($url, $method, $postfields = NULL) {
$this->http_info = array();
$ci = curl_init();
/* Curl settings */
curl_setopt($ci, CURLOPT_USERAGENT, $this->useragent);
curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $this->connecttimeout);
curl_setopt($ci, CURLOPT_TIMEOUT, $this->timeout);
curl_setopt($ci, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ci, CURLOPT_HTTPHEADER, array('Expect:'));
curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, $this->ssl_verifypeer);
curl_setopt($ci, CURLOPT_HEADERFUNCTION, array($this, 'getHeader'));
curl_setopt($ci, CURLOPT_HEADER, FALSE);
switch ($method) {
case 'POST':
curl_setopt($ci, CURLOPT_POST, TRUE);
if (!empty($postfields)) {
curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
}
break;
case 'DELETE':
curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
if (!empty($postfields)) {
$url = "{$url}?{$postfields}";
}
}
curl_setopt($ci, CURLOPT_URL, $url);
$response = curl_exec($ci);
$this->http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
$this->http_info = array_merge($this->http_info, curl_getinfo($ci));
$this->url = $url;
curl_close ($ci);
return $response;
}
/**
* Get the header info to store.
*/
function getHeader($ch, $header) {
$i = strpos($header, ':');
if (!empty($i)) {
$key = str_replace('-', '_', strtolower(substr($header, 0, $i)));
$value = trim(substr($header, $i + 2));
$this->http_header[$key] = $value;
}
return strlen($header);
}
}
Credit to #Pazi and #Rpg600 :)

Resources