I'm using this Flash Messages Script for a simple redirect and flash message system.
Everything works fine on my apache localhost, but as soon as I upload it to a server (also apache) it doesn't work. It sets the sessions and also displays the messages correctly, but it doesn't unset the messages afterwards. Now I have a whole bunch of "Flash messages" on my website and they'll get more and more unless you close your browser to unset all sessions forcefully.
I've already read the documentation like a thousand times and also searched in the Flash Messages script on the server for any errors. I couldn't find any.
Maybe you guys can help me. The host where I'll deploy my website is strato.com.
Edit: I found a cookie called PHPSESSID in my browser informations. Maybe this could be helpfull.
Constructor:
public function __construct()
{
// Generate a unique ID for this user and session
$this->msgId = sha1(uniqid());
// Create session array to hold our messages if it doesn't already exist
if (!array_key_exists('flash_messages', $_SESSION)) $_SESSION['flash_messages'] = [];
}
Clear session function:
protected function clear($types=[])
{
if ((is_array($types) && empty($types)) || is_null($types) || !$types) {
unset($_SESSION['flash_messages']);
} elseif (!is_array($types)) {
$types = [$types];
}
foreach ($types as $type) {
unset($_SESSION['flash_messages'][$type]);
}
return $this;
}
Add Sessions:
public function add($message, $type=self::defaultType, $redirectUrl=null, $sticky=false)
{
// Make sure a message and valid type was passed
if (!isset($message[0])) return false;
if (strlen(trim($type)) > 1) $type = strtolower($type[0]);
if (!array_key_exists($type, $this->msgTypes)) $type = $this->defaultType;
// Add the message to the session data
if (!array_key_exists( $type, $_SESSION['flash_messages'] )) $_SESSION['flash_messages'][$type] = array();
$_SESSION['flash_messages'][$type][] = ['sticky' => $sticky, 'message' => $message];
// Handle the redirect if needed
if (!is_null($redirectUrl)) $this->redirectUrl = $redirectUrl;
$this->doRedirect();
return $this;
}
I fixed it. It was due an change in PHP 7.1 in the php.ini file. As soon as I downgraded my PHP version to PHP 7.0 everything worked fine again.
I hope this will help a lot of people. At least you've got some starting point now.
Related
I have php function that is supposed to verify if there is a token, and if so, display some information. The function works fine when I use xampp in localhost. When I do it in prod on the server, it gives me a 'token undefined' error, even though I can see the token in dev tools. What could possibly be causing the error?
my php function
public function viewCompanies()
{
if (isset($GLOBALS['headers']['Authorization'])) {
print_r($GLOBALS['headers']['Authorization']);
if ($id = $this->VerifyUserToken($GLOBALS['headers']['Authorization'], $_SERVER['REMOTE_ADDR'])) {
$companies = $this->currentModel->viewCompanies();
if ($companies) {
echo json_encode($companies);
} else {
echo json_encode(['success' => false]);
}
}
else {
echo json_encode(['success' => false, 'error' => "invalid token"]);
}
} else {
echo json_encode(['success' => false, 'error' => "token undefined"]);
}
}
the verifyUserToken function
public function verifyUserToken($token, $ip) {
$db = new Database();
$db->query('SELECT * FROM auth WHERE token = :token AND expiry >now()');
$db->bind(':token', $token);
//check database if token exists and is not expired
if($res = $db->single()) {
// checks if token matches to ip address
// returns user or contact id if verified else returns false
if($res->token === $token && $res->ip === $ip) {
$this->cleanTokens();
if($res->user_id >0) {
return $res->user_id;
}
//
} else {
return false;
}
} else {
return false;
}
}
I checked the database, and the token is clearly there
I tested the function on Postman and I get the same token undefined error. Please let me know if there's any other info I should add. I've no idea how to debug this.
in the end. it was goDaddy that saved the day. They sent me the following message, after I opened a ticket and spoke with them:
In regards to the issue you are seeing with custom HTTP headers being stripped out of requests on your site, the issue you are running into is actually due to the CGI handler Apache is configured to use by default on cPanel. The CGI handler, for security reasons, strips out custom header entries that are not explicitly registered within Apache's configuration. We can further verify this by changing the PHP handler the site uses from CGI to PHP-FPM.
If you...please do not hesitate to contact our support teams over the phone or through live chat.
Sincerely,
all's well that ends well.
When logging in to the admin panel I am redirected to a url such as follows:
http://website.com/index.php/admin120487/index/index/key/3174c9146a5ab0ed3743085e265fa2f4/
The last key parameter is changed every time.
Can you guys suggest me how to fix this. The username and password is fine. But when submit it goes to this url with login page.
The issue is related to the php version. My Php version on server is 7.0 Something.
Now update and comment your files with following code
/public_html/app/code/core/Mage/Core/Model/Session/Abstract.php
public function renewSession()
{
/*$this->getCookie()->delete($this->getSessionName());
$this->regenerateSessionId();
$sessionHosts = $this->getSessionHosts();
$currentCookieDomain = $this->getCookie()->getDomain();
if (is_array($sessionHosts)) {
foreach (array_keys($sessionHosts) as $host) {
// Delete cookies with the same name for parent domains
if (strpos($currentCookieDomain, $host) > 0) {
$this->getCookie()->delete($this->getSessionName(), null, $host);
}
}
}*/
return $this;
}
I am attempting to use the Facebook PHP SDK in conjunction with CodeIgniter to allow users to login to my site using Facebook Connect. No matter what I try, getUser() always returns 0, even after (apparently) successful authentication via Facebook.
CodeIgniter version: 2.1.3
Facebook PHP SDK version: 3.2.2
I have created a config file, facebook.php, in the application/config folder and I am loading the Facebook PHP SDK via CodeIgniter's $this->load->library(...) method. The library is indeed getting loaded and I can successfully call many of the get...() methods including getAccessToken(), getAppId() and getAppSecret(), all of which return their expected values.
Here is a stripped down version of my login controller: (note that I also provide an alternate method of logging in via email, hence the CodeIgniter session code sprinkled throughout)
class Login extends CI_Controller {
public function __construct()
{
//Call parent constructor
parent::__construct();
//Magic sauce - not sure if this is required but a lot of other people
//are recommending it to be included (happy to remove it if necessary)
parse_str($_SERVER['QUERY_STRING'], $_REQUEST);
//Load facebook library
$facebook_config = $this->load->config('facebook');
$this->load->library('facebook', $facebook_config);
}
public function index()
{
//Check if user is logged in
$user_id = $this->session->userdata('user_id');
$is_logged_in = $this->session->userdata('is_logged_in');
if(($is_logged_in) && ($user_id != 0)) {
//Logged in - redirect to game
redirect('game');
} else {
//Not logged in
//Get facebook login url
$facebook_data = array(
'redirect_uri' => 'hxxp://xxxxxxxx.com/facebook_login/',
'scope' => 'email'
);
$data['facebook_login_url'] = $this->facebook->getLoginUrl($facebook_data);
//Redirect to login form
$this->load->view('login/login_form', $data);
}
}
public function facebook_login()
{
//Always returns 0!! Even after authenticating via facebook!
$facebook_user_id = $this->facebook->getUser();
if ($facebook_user_id) {
try {
$user_profile = $this->facebook->api('/me');
print_r($user_profile);
} catch (FacebookApiException $e) {
echo $e->getMessage();
}
} else {
echo "Could not log in with Facebook";
}
}
}
The stripped down view (login_form.php) is as follows:
<html>
<head>
<title>Facebook Connect Test</title>
</head>
<body>
<a href='<? echo $facebook_login_url; ?>'>Login with Facebook</a>
</body>
</html>
I have a route that redirects hxxp://xxxxxxxx.com/facebook_login to the login/facebook_login method, which is working.
I am running this code on a live development server.
My current flow is as follows:
Load hxxp://xxxxxxxx.com/ (Routes to login controller, which loads login_form view)
Click "Login with Facebook" link
Facebook asks me to login (which I do)
Facebook asks me to give permission to my app (which I do)
Facebook redirects me to the url specified in the redirect_uri parameter, which is identical to the one on the app settings page
And here's where it all goes wrong. The $this->facebook->getUser() method ALWAYS returns 0, even after authentication.
I have been scouring the Facebook developer documentation and everywhere else on the internet I can think of trying to find an answer to this. I have come across many posts similar to this and have tried to apply the solutions suggested, but to no avail.
What am I doing wrong?
The getCode() method in base_facebook.php uses the $_REQUEST global to store data. PHP 5.3.0 and greater uses the "request_order" param in php.ini, and by default $_REQUEST does not contain Cookie variables.
Per php.net (http://php.net/manual/en/ini.core.php#ini.request-order):
"This directive describes the order in which PHP registers GET, POST and Cookie variables into the _REQUEST array. Registration is done from left to right, newer values override older values.
If this directive is not set, variables_order is used for $_REQUEST contents.
Note that the default distribution php.ini files does not contain the 'C' for cookies, due to security concerns."
So it looks like your options are to modify the getCode() method like Max Power did above, or update your php.ini and add the "C" value to the request_order setting.
I managed to solve my problem. The questions linked to by Qweick and Stéphane Bruckert had the solution. The problem lies in the getCode() function of the base_facebook.php file.
The getCode() function needs to be modified. The modifications I used are listed below.
Existing non-working code:
protected function getCode() {
if (isset($_REQUEST['code'])) {
if ($this->state !== null &&
isset($_REQUEST['state']) &&
$this->state === $_REQUEST['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $_REQUEST['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
Modified working code:
protected function getCode() {
$server_info = array_merge($_GET, $_POST, $_COOKIE);
if (isset($server_info['code'])) {
if ($this->state !== null &&
isset($server_info['state']) &&
$this->state === $server_info['state']) {
// CSRF state has done its job, so clear it
$this->state = null;
$this->clearPersistentData('state');
return $server_info['code'];
} else {
self::errorLog('CSRF state token does not match one provided.');
return false;
}
}
return false;
}
The getUser() call now returns a valid user Id and the Facebook API calls now return valid data.
Thanks to everyone that helped point me in the right direction!
I have a working Yii app on my local lamp stack. Now when I put the app on a lamp server the app reads the db and runs, but the app isn't successfully writing to the db. I'm getting no errors logs. Any thoughts?
Here's how I'm updating the db:
public function actionIndex()
{
if ($_GET["yep"] == "") {
pd_error("You are not logged in!");
}
list($uid, $domain) = preg_split("/#/",$_GET["yep"],2);
$model=$this->loadModel($uid);
$this->redirect($model->URL."?".$model->Unique_ID);
}
public function loadModel($uid)
{
$model=People::model()->findByPk($uid);
$model->Login_Count++;
$model->Last_Logged=date('Y-m-d H:i:s');
if ($model->validate()) {
$model->save();
} else {
$this->render('notice');
}
return $model;
}
The weird thing is, even when the db doesn't update the Login_Count and Last_Logged the user still gets redirected to their url, so the sql must be valid because the notice page never loads. Any thoughts?
Update + Solution
The problem ended up being that the mysql server had autocommit set to false. To override this at the app level add the following line to the config/main.php db array:
'db'=>array(
...
'initSQLs'=>array('SET AUTOCOMMIT=1',),
...
);
Yii: using active record with autocommit off on mysql server
The rendering of notice page doesn't stop your redirect. It might be rendered, but you won't be able to see it because of redirect. Try to refactor your code.
You're validating your model twice and the validation probably might be skipped since there's no data coming from App user.
You don't check if People model actually found.
There is CWebUser::afterLogin method which you can override to do this kind of stuff (update login count and last login date)
Maybe this way (quick fix) will work:
function actionIndex()
{
if ($_GET["yep"] == "") {
pd_error("You are not logged in!");
}
list($uid, $domain) = preg_split("/#/",$_GET["yep"],2);
if (null === ($model=People::model()->findByPk($uid))
throw new CHttpException(404);
$model->Login_Count++;
$model->Last_Logged=date('Y-m-d H:i:s');
if ($model->save()) {
$this->redirect($model->URL."?".$model->Unique_ID);
} else {
// echo CHtml::errorSummary($model)
$this->render('notice');
}
}
I'm working on a small custom CMS and would like to implement flash messages. I have searched for hours, but I can't find anything that behaves the way I want. And I can't seem to make anything work.
I want to be able to pass a variable (via $_SESSION) to another page and, on that next request, it will be removed. I want to be able to use a keep_flash function, in case I don't want the message to be removed with the next server request.
Can anyone send me in the right direction? I can't really make anything work.
Thanks.
EDIT: Here is some code I am playing with. It sort-of works. When you first visit the page, it sets the $_SESSION and everything is fine. But if you refresh, now it deletes the $_SESSION. If you refresh again, it adds it back...etc. So, if you were to visit the page, refresh, then go to another page the flash message wouldn't be in the $_SESSION. So how can I fix this?
class flash
{
private $current = array();
private $keep = array();
public function __construct()
{
if (isset($_SESSION['flash'])) {
foreach($_SESSION['flash'] as $k=>$v)
{
$this->current[$k] = $v;
}
}
}
public function __destruct()
{
foreach ($this->current as $k=>$v)
{
if (array_key_exists($k,$this->keep) && $this->keep[$k] == $v) {
// keep flash
$_SESSION['flash'][$k] = $v;
} else {
// delete flash
unset($_SESSION['flash'][$k]);
unset($this->current[$k]);
unset($this->keep[$k]);
}
}
}
public function setFlash($key,$value)
{
$_SESSION['flash'][$key] = $value;
}
public function keepFlash($key)
{
$this->keep[$key] = $this->getFlash($key);
}
public function getFlash($key)
{
if (array_key_exists($key,$this->current)) return $this->current[$key];
return null;
}
}
basic idea is to have script always check specific variable in session (usually called 'flash') for content - if not empty display and delete it from session. When message is needed just place is same variable in session and next check would pick it up....
keep_flash in your case would not proceed with delete, or move to other place based on your needs.
for implementation just google it - usually it wrapped in some kind of class - I personally like phpclasses.org or part of framework