How does Yii2 Url::remember() work? - php

How does Url::remember() work? I thought it stores the URL in a cookie, but I don't see it. It's working locally, but not on Heroku.

According to source code, it saves URL in session:
public static function remember($url = '', $name = null)
{
$url = static::to($url);
if ($name === null) {
Yii::$app->getUser()->setReturnUrl($url);
} else {
Yii::$app->getSession()->set($name, $url);
}
}
setReturnUrl will call:
Yii::$app->getSession()->set($this->returnUrlParam, $url);
Official docs:
Session set()
User setReturnUrl()

Related

Symfony redirect in helper service does not work

Introduction
For my personal project i am using
Symfony v4.2 with
XAMPP and
Widows 10 Pro
In order to not to display route parameters in URL i save them in the table.
Then in the controller i check if there is variable (that keeps UUID that corresponds to route parameters) in the session.
If i get no variable in session it should redirect to section start page, where UUID and initial data in the table are setup.
Redirect logic is extracted to helper service. In order to redirect to work there are copied functions redirectToRoute and redirect
I test this functionalit by deleting php session variables in temp folder and PHPSESSID cookie in the browser.
Problem
The prolem is - it does not redirect to secton start page.
I can see that correct if branch is selected, but then it "just stops" and does not execute redirect.
Code
public function checkWhereaboutsExist()
{
$em = $this->entityManager;
$repo_whereabouts = $em->getRepository(Whereabouts::class);
$whereabouts = $this->session->get('whereabouts');
if (($whereabouts === null) || ($whereabouts === ''))
{
$data = 'whereabouts === '.$whereabouts;
dump($data);
/*
HERE IT STOPS
*/
return $this->redirectToRoute('section_start');
}
else
{
$my_whereabouts = $repo_whereabouts->getWhereabouts($whereabouts);
if (!$my_whereabouts)
{
return $this->redirectToRoute('section_start');
}
}
}
Question
Does enyone have some ideas about what is the culprit in this case?
You could try to inject the router into your service class:
use Symfony\Component\Routing\RouterInterface;
class MyService
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function checkWhereaboutsExist()
{
// your code ...
return new RedirectResponse($this->router->generate('section_start'));
}
}
Hummmm, i suppose that your code is in a service and not in your controller ?
You can't redirect from a service but only from controller as controller send the final response.
You have to return a boolean from your service and redirect from your controller :
public function hasToGoToStart()
{
$em = $this->entityManager;
$repo_whereabouts = $em->getRepository(Whereabouts::class);
$whereabouts = $this->session->get('whereabouts');
if (($whereabouts === null) || ($whereabouts === ''))
{
return true;
}
else
{
$my_whereabouts = $repo_whereabouts->getWhereabouts($whereabouts);
if (!$my_whereabouts)
{
return true;
}
}
return false;
}
and in your controller :
if ($myService->hasToGoToStart()) {
// redirect
}

Codeigniter REST. How to properly protect against csrf

I am using the REST server by Phil Sturgeon and I was wondering how I can do CSRF Protection properly? Currently I am using this method:
if(stripos($_SERVER["REQUEST_URI"],'API')!=""){
$config['csrf_protection'] = FALSE;
}else{
$config['csrf_protection'] = TRUE;}
However, I have read that this is not the proper way to protect against csrf attacks. I have tried to extend MY_Security but I am unsure of what I need to do after I extend the class. This is the extended class
defined('BASEPATH') OR exit('No direct script access allowed');
class MY_Security extends CI_Security {
public function csrf_verify()
{
// If it's not a POST request we will set the CSRF cookie
if (strtoupper($_SERVER['REQUEST_METHOD']) !== 'POST')
{
return $this->csrf_set_cookie();
}
/**
* mine implementation for application/json
*/
$reqHeaders = getallheaders();
$content_type = $reqHeaders["Content-Type"];
#it's a json request?
if(preg_match("/(application\/json)/i",$content_type))
{
#the check the cookie from request
$reqCookies = explode("; ",$reqHeaders["Cookie"]);
foreach($reqCookies as $c)
{
if(preg_match("/(".$this->_csrf_cookie_name."\=)/", $c))
{
$c = explode("=",$c);
if($_COOKIE[$this->_csrf_cookie_name] == $c[1])
{
return $this;
}
}
}
}
//< end
// Check if URI has been whitelisted from CSRF checks
if ($exclude_uris = config_item('csrf_exclude_uris'))
{
$uri = load_class('URI', 'core');
foreach ($exclude_uris as $excluded)
{
if (preg_match('#^'.$excluded.'$#i'.(UTF8_ENABLED ? 'u' : ''), $uri->uri_string()))
{
return $this;
}
}
}
// Do the tokens exist in both the _POST and _COOKIE arrays?
if ( ! isset($_POST[$this->_csrf_token_name], $_COOKIE[$this->_csrf_cookie_name])
OR $_POST[$this->_csrf_token_name] !== $_COOKIE[$this->_csrf_cookie_name]) // Do the tokens match?
{
$this->csrf_show_error();
}
// We kill this since we're done and we don't want to polute the _POST array
unset($_POST[$this->_csrf_token_name]);
// Regenerate on every submission?
if (config_item('csrf_regenerate'))
{
// Nothing should last forever
unset($_COOKIE[$this->_csrf_cookie_name]);
$this->_csrf_hash = NULL;
}
$this->_csrf_set_hash();
$this->csrf_set_cookie();
log_message('info', 'CSRF token verified');
return $this;
}
}
Do I need to set headers for each json POST or get request? This is an example of what I send to my REST backend
public function user_create_activity($activity){
$this->curl->create(UserCreateActivity);
$this->curl->http_login(REST_KEY_ID,REST_KEY_PASSWORD);
$this->curl->post(array(
'activity' => $activity,
));
return json_decode($this->curl->execute(),true);
}
I am quite unsure if I am on the right path. Hopefully someone can guide me.
Thank you.

After switching from file to session vars the functions don't work

I have two methods which work without problems
public static function appendGamer($gamer) {
file_put_contents(self::$fileName, $gamer, FILE_APPEND);
}
and
private function selectLastGamer() {
$gamers = file(self::$fileName);
if (sizeof($gamers) > self::$totalGamers) {
self::$totalGamers = sizeof($gamers);
return trim($gamers[self::$totalGamers - 1]);
}
return "";
}
Now I want everything to be stored in session vars rather than traditional text files. So i rewrite these functions the following way
public static function appendGamer($gamer) {
$old = trim($_SESSION["gamers"]);
$_SESSION["gamers"] = ($old == "") ? $gamer : $old . PHP_EOL . $gamer;
}
and
private function selectLastGamer() {
$gamers = explode(PHP_EOL, $_SESSION["gamers"]);
if (sizeof($gamers) > self::$totalGamers) {
self::$totalGamers = sizeof($gamers);
return trim($gamers[self::$totalGamers - 1]);
}
return "";
}
But now these functions don't work. I mean now selectLastGamer always returns empty string. The session variable is automatically created in constructor so it is always set. What's wrong with new version of these functions?
You should start session on every page like
if( session_status() != PHP_SESSION_DISABLED )
{
session_start();
}
OR
if( session_status() == PHP_SESSION_NONE || session_status() == PHP_SESSION_ACTIVE)
{
session_start();
}
Because session_status() returns any one of the following value at a time.
PHP_SESSION_DISABLED if sessions are disabled.
PHP_SESSION_NONE if sessions are enabled, but none exists.
PHP_SESSION_ACTIVE if sessions are enabled, and one exists.
Hope it ll work for you.
Start session on every page you want to access the session variable set/get using session_start(); at the top of the page.
On main page and also on the page where functions are defined.

generating goo.gl not working on localhost

i am trying to dynamically generate the goo.gl links via function.php ,when a post is created ...but its not getting updating the field with the link created on localhost..and i just cant figure out the issue
function newlinks($post_id){
$permaurl=get_permalink($post_id);
$shorturl=make_my_url($permaurl);
update_post_meta('$post_id','shorturl',$shorturl)
}
add_action( 'save_post', 'newlinks' );
function make_my_url($myurl)
{
//got te key from https://console.developers.google.com/iam-admin/projects
$key = 'AIzBP0';
$googer = new GoogleURLAPI($key);
// Test: Shorten a URL
$shortDWName = $googer->shorten($myurl);
return $shortDWName; // returns the short url
}
// Declare the class
class GoogleUrlApi {
// Constructor
function GoogleURLAPI($key,$apiURL = 'https://www.googleapis.com/urlshortener/v1/url') {
// Keep the API Url
$this->apiURL = $apiURL.'?key='.$key;
}
// Shorten a URL
function shorten($url) {
// Send information along
$response = $this->send($url);
// Return the result
return isset($response['id']) ? $response['id'] : false;
}
// Send information to Google
function send($url,$shorten = true) {
// Create cURL
$ch = curl_init();
// If we're shortening a URL...
if($shorten) {
curl_setopt($ch,CURLOPT_URL,$this->apiURL);
curl_setopt($ch,CURLOPT_POST,1);
curl_setopt($ch,CURLOPT_POSTFIELDS,json_encode(array("longUrl"=>$url)));
curl_setopt($ch,CURLOPT_HTTPHEADER,array("Content-Type: application/json"));
}
else {
curl_setopt($ch,CURLOPT_URL,$this->apiURL.'&shortUrl='.$url);
}
curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
// Execute the post
$result = curl_exec($ch);
// Close the connection
curl_close($ch);
// Return the result
return json_decode($result,true);
}
}
your code is good. I've created my own API key and tried this and works fine. The problem may be in google console.
Please login to https://developers.google.com/apis-explorer/?hl=pl#p/urlshortener/v1/ and try to generate short url there. Google should ask you to authorize the key you created before. After that code should work fine.

Clear cookies in yii2 after function call

I am facing some issues regarding clearing cookies in yii2. When i am calling a logout function on button click i am trying to perform following actions:
Set authtoken, and its expiration value to null
if Step got performed then clear session and cookies
but the problem is after setting the authtoken and its expiration value to null control is not going under if block (Where i am clearing session and cookies).
public function actionLogout()
{
$userId = \Yii::$app->user->identity->id;
$restobj = new RestController();
$this->token = NuLL;
$expire = Null;
$data = ['userId'=>$userId,'token'=>$this->token,'expire'=>$expire];
$data = json_encode($data);
$authtoken = $restobj->updateItem(\app\urls\urls::setauthtoken, $data);
if($authtoken)
{
$session = new Session();
$session->close();
$session->destroy();
$cookies = \Yii::$app->response->cookies;
unset($cookies['user_cookies']);
Yii::$app->user->logout();
return $this->goHome();
}
}
updateItem function is calling this authtoken function:
<?php
namespace app\actions\userloginactions;
use Yii;
use yii\rest\ActiveController;
use app\models\Authmaster;
use yii\base\Action;
class AuthtokenAction extends Action
{
//function used in rest api call for user token
public function run()
{
$data = Yii::$app->getRequest()->getBodyParams();
$userId = $data['userId'];
$token = $data['token'];
$expire = $data['expire'];
$result = Authmaster::setauthtoken($userId,$token,$expire);
return true;
}
}
setauthtoken function in model called from AuthtokenAction
public static function setauthtoken($userId,$token,$expire)
{
return Authmaster::updateAll(['token'=>$token,'expire'=>$expire],['user_id'=>$userId]);
}
when i click logout button it successfully sets the authtoken and expiration to null but it directly displays true as a result of AuthtokenAction function and control doesn't goes under if block.
that function call is creating some problem if i comment that and write cookies clearing block directly then cookies gets cleared without any problem.
Please check following code to clear all cookies. It is working for me, hope will work for you too.
Yii::$app->cache->flush()
Please try to use following line
$cookies = Yii::$app->response->cookies;
$cookies->remove('user_cookies');
Can you try this one?
if (isset($_SERVER['HTTP_COOKIE'])) {
$cookies = explode(';', $_SERVER['HTTP_COOKIE']);
foreach($cookies as $cookie) {
$parts = explode('=', $cookie);
$name = trim($parts[0]);
setcookie($name, '', time()-1000);
setcookie($name, '', time()-1000, '/');
}
}
Hope this helps others...
$cookies = Yii::$app->response->cookies;
$cookies->remove('username');
unset($cookies['username']);
Found in the following referenced link: http://www.bsourcecode.com/yiiframework2/cookies-handling-in-yii-framework2-0/

Categories