I would like to save sessions and cookies as discord does. What i mean? I mean when user sign in to discord account on browser and delete all cookies/session on browser by clicking padlock and cookies. When that will deleted everytime session file is created. And when i refresh site i was still logged on account. I want do something on this same way but when i use session, cookies, Header (to header i cant add expires date) And delete cookies by this same way it not adding that again because my script cant get any information about user. I thinking to do a JavaScript while to add every second sessionstorage or localstorage. And check that everytime when user open site but that is not good for optimalization. So anyone had idea how to do that?
Update
CreateInfo.php
<?php
namespace Client\Info;
use Client\Info\CheckInfo;
use Client\Info\SetInfo;
class CreateInfo
{
public function __construct()
{
$this->checkInfo = new CheckInfo();
$this->setInfo = new SetInfo();
$this->status = $this->checkInfo->getStatus();
}
public function control()
{
if($this->status['session'] && $this->status['cookie'] && $this->status['sameCookieSession']){
if(!$this->checkInfo->checkIpStatus()){
$this->setInfo->addIp(true, true, true);
}
}else if($this->status['session'] && $this->status['cookie'] && !$this->status['sameCookieSession']){
$this->setInfo->addCookie(true);
if(!$this->checkInfo->checkIpStatus()){
$this->setInfo->addIp(true, true, false);
}
}else if($this->status['session'] && !$this->status['cookie']){
$this->setInfo->addCookie(true);
if(!$this->checkInfo->checkIpStatus()){
$this->setInfo->addIp(true, false, false);
}
}else if(!$this->status['session'] && $this->status['cookie']){
$this->setInfo->addSession(true);
if(!$this->checkInfo->checkIpStatus()){
$this->setInfo->addIp(false, true, false);
}
}else{
$this->setInfo->setAll();
}
}
public function run()
{
$this->control();
}
}
CheckInfo.php
<?php
namespace Client\Info;
use Client\Info\InfoDatabase;
use Client\Cookie\CookieFunction;
use Client\Session\SessionFunction;
use Client\Ip\IpFunction;
class CheckInfo
{
public function __construct()
{
$this->infoDatabase = new InfoDatabase();
$this->cookieFunction = new CookieFunction();
$this->sessionFunction = new SessionFunction();
$this->ipFunction = new IpFunction();
$this->session = $this->sessionFunction->getSession('client');
$this->cookie = $this->cookieFunction->getCookie('client');
}
public function checkExist($data)
{
if(!isset($data) || empty($data)){
return false;
}
if(!$this->infoDatabase->checkExistInDb($data)){
return false;
}
return true;
}
public function getStatus()
{
if($this->checkExist($this->cookie)){
if($this->checkExist($this->session)){
if($this->cookie == $this->session){
return[
'session' => true,
'cookie' => true,
'sameCookieSession' => true
];
}else{
return[
'session' => true,
'cookie' => true,
'sameCookieSession' => false
];
}
}else{
return[
'session' => false,
'cookie' => true,
'sameCookieSession' => false
];
}
}else{
if($this->checkExist($this->session)){
return[
'session' => true,
'cookie' => false,
'sameCookieSession' => false
];
}else{
return[
'session' => false,
'cookie' => false,
'sameCookieSession' => false
];
}
}
}
public function checkIpStatus()
{
$ip = $this->ipFunction->getIp();
$result = false;
if($this->getStatus()['session']){
$result = $this->infoDatabase->checkExistIpInDb($this->session, $ip);
}else if($this->getStatus()['cookie']){
$result = $this->infoDatabase->checkExistIpInDb($this->cookie, $ip);
}
return $result;
}
}
SetInfo.php
<?php
namespace Client\Info;
use Client\Info\InfoDatabase;
use Client\Cookie\CookieFunction;
use Client\Session\SessionFunction;
use Client\Ip\IpFunction;
use Client\Currency\CurrencyFunction;
use App\Element\Random\RandomString;
class SetInfo
{
public function __construct()
{
$this->infoDatabase = new InfoDatabase();
$this->cookieFunction = new CookieFunction();
$this->sessionFunction = new SessionFunction();
$this->ipFunction = new IpFunction();
$this->currencyFunction = new CurrencyFunction();
$this->randomString = new RandomString();
$this->cookie = $this->cookieFunction->getCookie('client');
$this->session = $this->sessionFunction->getSession('client');
}
public function addIp($session, $cookie, $sameCookieSession)
{
$ip = $this->ipFunction->getIp();
if($sameCookieSession){
$this->infoDatabase->addIp($this->cookie, $ip);
}else{
if($session){
$this->infoDatabase->addIp($this->session, $ip);
}else if($cookie){
$this->infoDatabase->addIp($this->cookie, $ip);
}
}
}
public function addCookie($session)
{
if($session){
$this->cookieFunction->setCookie('client', $this->session);
}
}
public function addSession($cookie)
{
if($cookie){
$this->sessionFunction->setSession('client', $this->cookie);
}
}
public function setAll()
{
$rand = $this->randomString->generate(128);
$ip = $this->ipFunction->getIp();
$currency = $this->currencyFunction->getCurrencyCode();
$this->infoDatabase->addCookie($rand);
$this->infoDatabase->addIp($rand, $ip);
$this->infoDatabase->addCurrency($rand, $currency);
$this->cookieFunction->setCookie('client', $rand);
$this->sessionFunction->setSession('client', $rand);
}
}
Related
So I am currently coding a user registration in PHP 5.6.10 and just discovered something weird: The function Token::check(Input::get('token')) returns a boolean. If it returns true, the if-statement is getting executed. Works fine so far, however when I var_dump it previous to the if-statement, the if-statement is not being executed.
Is there any explanation for this behaviour?
var_dump(Token::check(Input::get('token')));
if(Input::exists()) {
if(Token::check(Input::get('token'))) {
echo "Loop.";
$validate = new Validate();
$validation = $validate->check($_POST, array(
'first_name' => array(
'required' => true,
'min' => 1,
'max' => 50
)
));
if($validation->passed()) {
echo "Die Eingaben waren korrekt.";
} else {
foreach ($validation->errors() as $error) {
echo $error,"<br>";
}
echo "<br>";
}
}
}
(I hope I didn't make a typo when shortening the code)
Here is the check()-function as requested:
public static function check($token) {
$tokenName = Config::get('session/token_name');
if(Session::exists($tokenName) && $token === Session::get($tokenName)) {
Session::delete($tokenName);
return true;
}
return false;
}
Based on the code from the check method:
public static function check($token) {
$tokenName = Config::get('session/token_name');
if(Session::exists($tokenName) && $token === Session::get($tokenName)){
Session::delete($tokenName);
return true;
}
return false;
}
In the first time that you call:
var_dump(Token::check(Input::get('token')));
it deletes the token from the session, preventing the condition:
if(Token::check(Input::get('token'))) to be met.
Maybe you can put an extra param in the check function just to help you debug and not delete the token:
public static function check($token, $test = false) {
$tokenName = Config::get('session/token_name');
if(Session::exists($tokenName) && $token === Session::get($tokenName)){
if (!$test) {
Session::delete($tokenName);
}
return true;
}
return false;
}
Iḿ trying to make an rest application using Phalcon, i save some of the info
of the logged in user in an session but i don't get this to work, my code:
$this->session->set( Sessions::USERINFO, array (
'login' => true,
'type' => UserTypes::ADMIN,
'username' => $this->user->getUsername(),
'adminid' => $this->user->getAdminID(),
'fullname' => $this->user->getFullName(),
'avatar' => $this->user->getAvatar() )
);
return $this->session->get( Sessions::USERINFO );
When he returns the session it works but when i try to get the session in an other request it returns empty
return array("session" => $this->session->isStarted(),
"session Data" => $this->session->get(Sessions::USERINFO));
isStarted returns true
get returns null
Sessions::USERINFO
is an class with const values
const USERINFO = "userInfo";
Session var creation
$di->setShared( 'session', function () {
$session = new Session();
$session->start();
return $session;
} );
I am using this to save my session:
$obj = $this->request->getJsonRawBody();
$user = Users::findFirstByUsername($obj->username);
if($user) {
if($this->security->checkHash($obj->password, $user->password)) {
unset($user->password);
$this->session->set('auth', $user->toArray());
$response = $user->toArray();
}
else {
$response = array('msg' => 'failed');
}
}
else {
$response = array('error' => 'User not found');
}
$this->setPayload($response);
return $this->render();
And this to recieve information from my session
if($this->session->get('auth')['username']) {
$response = $this->session->get('auth');
}
else {
$response = array('msg' => 'noInfo');
}
$this->setPayload($response);
return $this->render();
This is how I start my session:
$di->set('session', function () {
$session = new SessionAdapter();
$session->start();
return $session;
});
It works just fine, you might want to try this.
I found the problem. Had to enable this in my frondend application:
RestangularProvider.setDefaultHttpFields({
withCredentials: true
});
The frontend was not sending the cookie with every request.
I am working on a simple anonymous login system and I have a Session class which looks like this:
<?php
class Session
{
private static $cookieLifeSpanInDays;
public function __construct()
{
self::$cookieLifeSpanInDays = 1825;
}
public static function loginUser()
{
if (!Session::isLoggedIn())
{
// Login User
$session_id = Session::newSessionId();
$name = Session::newUserName($session_id);
if (empty($name))
throw new Exception('Failed to generate a unique user name. Try again later.');
DB::insert('users', array(
'name' => $name,
'session_id' => $session_id,
'last_login' => time()
));
setcookie("sessionId", $session_id, time() + (self::$cookieLifeSpanInDays * 86400), '/', $_SERVER['HTTP_HOST']);
$_SESSION['isLoggedIn'] = true;
var_dump(self::$cookieLifeSpanInDays);
var_dump($_COOKIE);
exit();
}
// Defaults
return true;
}
}
When I call the class like this: Session::loginUser();
The var_dumps() in the loginUser function looks like this:
So, my login function is broken (no cookie is getting set) because the static property on class self::$cookieLifeSpanInDays is null. What am I doing wrong here?
I've fixed it:
<?php
class Session
{
private static $cookieLifeSpanInDays = 1825;
public static function loginUser()
{
if (!Session::isLoggedIn())
{
// Login User
$session_id = Session::newSessionId();
$name = Session::newUserName($session_id);
if (empty($name))
throw new Exception('Failed to generate a unique user name. Try again later.');
DB::insert('users', array(
'name' => $name,
'session_id' => $session_id,
'last_login' => time()
));
setcookie("sessionId", $session_id, time() + (self::$cookieLifeSpanInDays * 86400));
$_SESSION['isLoggedIn'] = true;
var_dump(self::$cookieLifeSpanInDays);
var_dump($_COOKIE);
exit();
}
// Defaults
return true;
}
}
I have this code:
if (strtolower($_POST['skype']) == "yummy")
echo "<pre>".file_get_contents("./.htfullapps.txt")."</pre>";
elseif ($_POST['skype'] == '' or
$_POST['IGN'] == '' or
$_POST['pass'] == '' or
!isset($_POST['rules']) or
!isset($_POST['group']) or
strlen($_POST['pass']) <= 7)
{
redir( "http://ftb.chipperyman.com/apply/?fail&error=one%20or%20more%20fields%20did%20not%20meet%20the%20minimum%20requirements" ); //Redir is a function defined above and works fine.
exit;
}
However, I would like to start reporting specific errors. For example, this is how I would do it with if statements:
...
elseif ($_POST['skype'] == '') redir( "http://ftb.chipperyman.com/apply/?fail&error=your%20skype%20is%20invalid%20because%20it%20is%20empty" );
elseif ($_POST['IGN'] == '') redir( "http://ftb.chipperyman.com/apply/?fail&error=your%20IGN%20is%20invalid%20because%20it%20is%20empty" );
elseif ($_POST['pass'] == '') redir( "http://ftb.chipperyman.com/apply/?fail&error=your%20password%20is%20invalid%20because%20it%20is%20empty" );
elseif (strlen($_POST['pass']) <= 7) redir( "http://ftb.chipperyman.com/apply/?fail&error=your%20password%20is%20invalid%20because%20it%20does%20not%20meet%20minimum%20length%20requirements" );
...
However that's big, messy and inefficient. What would a solution to this be?
You could use associative array like this.
function redir($var){
echo $var;
}
$skypeErr = array(''=>"http://ftb.chipperyman.com/apply/?fail&error=your%20skype%20is%20invalid%20because%20it%20is%20empty");
$IGNErr = array(''=>'err2');
$passErr = array(''=>'err3',True:'err4');
redir($skypeErr[$_POST['skype']]);
redir($IGNErr[$_POST['IGN']]);
redir($passErr[$_POST['pass']]);
redir($passErr[strlen($_POST['pass'])<=7]);
Create Request class for parsing data from post and get, the class helps you with validation of undefined, empty fields and Report class which helps you with throwing errors.
Here is the very simple Request class:
class Request {
protected $items = array(
'get' => array(),
'post' => array()
);
public function __construct(){
$this->items['post'] = $_POST;
$this->items['get'] = $_GET;
}
public function isPost(){
return ($_SERVER['REQUEST_METHOD'] == 'POST') ? true : false;
}
public function isGet(){
return ($_SERVER['REQUEST_METHOD'] == 'GET') ? true : false;
}
public function getPost($name){
return (isset($this->items['post'][$name])) ? $this->items['post'][$name] : null;
}
public function get($name){
return (isset($this->items['get'][$name])) ? $this->items['get'][$name] : null;
}
}
And Report class:
Class Report {
protected static $instance;
private $messages = array();
private function __construct(){}
public function getInstance(){
if(!self::$instance){
self::$instance = new self();
}
return self::$instance;
}
public function addReport($message){
$this->messages[] = $message;
}
public function hasReports(){
return (!empty($this->messages)) ? true : false;
}
public function getReports(){
return $this->messages;
}
//this is not so cleaned .... it must be in template but for example
public function throwReports(){
if(!empty($this->messages)){
foreach($this->messages as $message){
echo $message."<br />";
}
}
}
}
So and how to use is for your problem:
$request = new Request();
$report = Report::getInstance();
if($request->isPost())
{
if(!$request->getPost("icq")){
$report->addMessage("you dont enter ICQ");
}
if(!$request->getPost("skype")){
$report->addMessage("you dont enter SKYPE");
}
//....etc
//if we have some reports throw it.
if($report->hasReports()){
$reports->throwReports();
}
}
The report class you can combine with sessions and throw errors after redirect, just update the class to saving reports to session instead of $messages, and after redirect if u will be have messages throw it and clear at the same time.
how about
$field_min_len = array('skype' => 1, 'IGN' => 1, 'pass' => 7);
for ($field_min_len as $f => $l) {
if (!isset($_POST[$f]) || strlen($_POST[$f]) < $l) {
redir(...);
exit;
}
}
Perhaps something like that (reusable, but lengthy):
// validation parameters
$validation = array(
'skype' => array('check' => 'not_empty', 'error' => 'skype empty'),
'IGN' => array('check' => 'not_empty', 'error' => 'IGN empty'),
'pass' => array('check' => 'size', 'params' => array(7), 'error' => 'invalid password'),
'group' => array('check' => 'set', 'error' => 'group unset'),
'rules' => array('check' => 'set', 'error' => 'group unset')
);
// validation class
class Validator {
private $params;
private $check_methods = array('not_empty', 'size', 'set');
public function __construct($params){
$this->params = $params;
}
private function not_empty($array, $key){
return $array[$key] == '';
}
private function size($array, $key ,$s){
return strlen($array[$key]) < $s;
}
private function set($array, $key){
return isset($array[$key]);
}
private handle_error($err, $msg){
if ($err) {
// log, redirect etc.
}
}
public function validate($data){
foreach($params as $key => $value){
if (in_array($value['check'], $this->check_methods)){
$params = $value['params'];
array_unshift($params, $data, $key);
$this->handler_error(call_user_func_array(array($this,$value['check']),
$params),
$value['error']);
}
}
}
};
// usage
$validator = new Validator($validation);
$validator->validate($_POST);
Just expand the class with new checks, special log function etc.
Warning: untested code.
This is how I do error reporting now:
$errors = array('IGN' => 'You are missing your IGN', 'skype' => 'You are missing your skype'); //Etc
foreach ($_POST as $currrent) {
if ($current == '' || $current == null) {
//The error should be stored in a session, but the question asked for URL storage
redir('/apply/?fail='.urlencode($errors[$current]));
}
}
I have successfully used Auth, but unfortunately, it seems that it does work only with Session. I want that if user checks "Remember Me" checkbox, I would use Cookie and he would be logged in for 2 weeks. I can't find anything in official book and in Google I found just few and not great blog posts. Is there any way to implement this without rewriting the core?
In your user controller:
public function beforeFilter() {
$this->Auth->allow(array('login', 'register'));
parent::beforeFilter();
}
public function login() {
if ($this->request->is('post')) {
if ($this->Auth->login()) {
// did they select the remember me checkbox?
if ($this->request->data['User']['remember_me'] == 1) {
// remove "remember me checkbox"
unset($this->request->data['User']['remember_me']);
// hash the user's password
$this->request->data['User']['password'] = $this->Auth->password($this->request->data['User']['password']);
// write the cookie
$this->Cookie->write('remember_me_cookie', $this->request->data['User'], true, '2 weeks');
}
return $this->redirect($this->Auth->redirect());
} else {
$this->Session->setFlash(__('Username or password is incorrect.'));
}
}
$this->set(array(
'title_for_layout' => 'Login'
));
}
public function logout() {
// clear the cookie (if it exists) when logging out
$this->Cookie->delete('remember_me_cookie');
return $this->redirect($this->Auth->logout());
}
In the login view:
<h1>Login</h1>
<?php echo $this->Form->create('User'); ?>
<?php echo $this->Form->input('username'); ?>
<?php echo $this->Form->input('password'); ?>
<?php echo $this->Form->checkbox('remember_me'); ?> Remember Me
<?php echo $this->Form->end('Login'); ?>
In your AppController:
public $components = array(
'Session',
'Auth',
'Cookie'
);
public $uses = array('User');
public function beforeFilter() {
// set cookie options
$this->Cookie->key = 'qSI232qs*&sXOw!adre#34SAv!#*(XSL#$%)asGb$#11~_+!##HKis~#^';
$this->Cookie->httpOnly = true;
if (!$this->Auth->loggedIn() && $this->Cookie->read('remember_me_cookie')) {
$cookie = $this->Cookie->read('remember_me_cookie');
$user = $this->User->find('first', array(
'conditions' => array(
'User.username' => $cookie['username'],
'User.password' => $cookie['password']
)
));
if ($user && !$this->Auth->login($user['User'])) {
$this->redirect('/users/logout'); // destroy session & cookie
}
}
}
See this URL i think it is very help full to you.
http://lecterror.com/articles/view/cakephp-and-the-infamous-remember-me-cookie
Or Try this
function login() {
if ($this->Auth->user()) {
if (!empty($this->data) && $this->data['User']['remember_me']) {
$cookie = array();
$cookie['username'] = $this->data['User']['username'];
$cookie['password'] = $this->data['User']['password'];
$this->Cookie->write('Auth.User', $cookie, true, COOKIE_EXPIRE);
unset($this->data['User']['remember_me']);
}
$this->LogDetail->Write('activity','has logged IN');
$this->redirect($this->Auth->redirect());
}
if (empty($this->data)) {
$cookie = $this->Cookie->read('Auth.User');
if (!is_null($cookie)) {
if ($this->Auth->login($cookie)) {
$this->Session->destroy('Message.Auth'); # clear auth message, just in case we use it.
$this->LogDetail->Write('activity','has been authenticated via cookie and is now logged IN');
$this->redirect($this->Auth->redirect());
} else {
$this->LogDetail->Write('activity','attempted to gain access with an invalid cookie');
$this->Cookie->destroy('Auth.User'); # delete invalid cookie
$this->Session->setFlash('Invalid cookie');
$this->redirect('login');
}
}
}
}
use CookeAuthenticate adapter:
https://github.com/ceeram/Authenticate/blob/master/Controller/Component/Auth/CookieAuthenticate.php
here more info:
https://github.com/ceeram/Authenticate/wiki/Set-Cookie
Remember me is nothing else but session identified with a cookie, but cookie lifetime set to infinity. Look at Config/core.php for session cookie lifetime.
I think you need to know about CakePHP Security levels. Try to lower the security of your cakePHP. CakePHP's Config variables documentation. I had written a blog about it also a long ago.
you can try this
if ($this->Auth->login())
{
if (!empty($this->data['User']['remember']))
{
$cookie = array();
$cookie['login'] = $this->data['User']['login'];
$cookie['password'] = $this->data['User']['password'];
$cookie['language'] =$this->data['User']['language'];
$this->Cookie->write('Auth.projectname', $cookie, true, '+1 years');
unset($this->data['User']['remember']);
public function admin_login() {
$this->layout = 'admin_login';
if (count($this->Session->read("Auth.User"))) {
$usr = $this->Session->read("Auth.User");
if ($usr['role'] == 'A' || $usr['role'] == 'RA' || $usr['role'] == 'MAfA' || $usr['role'] == 'Af' || $usr['role'] == 'FAA')
return $this->redirect(array('controller' => 'dashboard', 'action' => 'view'));
}
if ($this->request->is('post')) {
if ($this->request->data['User']['remember_me']=="1") {
// pr($this->request->data);
// die('sdd');
$this->Cookie->write('username', $this->request->data['User']['username'], true, '1 year');
$this->Cookie->write('password', $this->request->data['User']['password'], true, '1 year');
} else {
$this->Cookie->destroy();
}
/*
* Check if email or username is passed in form
*/
$uname = $this->request->data['User']['username'];
//login via email
if (filter_var($uname, FILTER_VALIDATE_EMAIL)) {
$u = $this->User->findByemail($uname);
} else { //login via username
$u = $this->User->findByusername($uname);
}
if ($u) {
$this->request->data['User']['username'] = $u['User']['username'];
/* * *
* Error if user is not active
*/
if ($u['User']['user_status'] != 'active') {
$this->Session->setFlash(__('Sorry! Your account is not active.'), 'default', array('class' => 'alert alert-danger'));
} elseif ($this->Auth->login()) { //if logged in
$user_caps = $this->fetchCapabilitiesByRole($u['User']['role']);
$this->Session->write("Auth.User.privileges", array('capabilities' => $user_caps['capabilities'], 'geo_areas' => array()));
if ($u['User']['role'] == 'A' || $u['User']['role'] == 'RA' || $u['User']['role'] == 'Af' || $u['User']['role'] == 'MAfA' || $u['User']['role'] == 'FAA')
return $this->redirect(array('controller' => 'dashboard', 'action' => 'view'));
return $this->redirect($this->Auth->redirect());
}else { //if invalid
$this->Session->setFlash(__('Invalid username or password.'), 'default', array('class' => 'alert alert-danger'));
}
} else {//if user does not exists
$this->Session->setFlash(__('User does not exists.'), 'default', array('class' => 'alert alert-danger'));
}
}
}
It's been a while since the question was answered but hopefully this can help to ones that come after me.
I've written short walkthrough on how to setup 'remember me' functionality using Auhenticate Plugin from Ceeram
More info here: http://mirkoborivojevic.com/posts/2013/08/10/setup-remember-me-functionality-in-cakephp/