I am using PhpMyAdmin and a custom single-sign on (SSO) script for direct login into the interface. The SSO script is called by PHP, given a unique login token by my own system. This script looks up the unique id in my system in order to retrieve MySQL username and password and returns this back to PhpMyAdmin.
This is working so far, but my next goal is automatic logout after a certain amount of inactivity. Without SSO, deleting my browser cookies and clicking any link, I get to the login page with the message »Your session has expired. Please log in again.«. However, I'm not able to reproduce this behavior from within my SSO script.
This is my SSO script:
<?php
/**
* Session timeout in seconds.
*/
define('SESSION_TIMEOUT', 60);
/**
* #return array|null Returns an array with login credentials or null for no login.
*/
function get_login_credentials() {
parse_str($_SERVER['QUERY_STRING'], $query);
/* check for session activity (timeout) */
if (isset($_SESSION['ssoLastActivity']) && (time() - $_SESSION['ssoLastActivity']) > SESSION_TIMEOUT) {
$sessionExpired = true;
} else {
$sessionExpired = false;
}
if (isset($query['old_usr'])) {
/* logout and back to index page */
unset($_SESSION['ssoLastActivity']);
unset($_SESSION['ssoUser']);
unset($_SESSION['ssoPassword']);
header('Location: index.php');
exit;
}
if ($sessionExpired) {
unset($_SESSION['ssoLastActivity']);
unset($_SESSION['ssoUser']);
unset($_SESSION['ssoPassword']);
/******** POINT OF QUESTION ********/
/* I'm trying to give the same response as if the cookies were deleted.
I land on the login page as desired, however I'm missing the session
timeout message. */
header('Content-Type: application/json');
echo json_encode(['redirect_flag' => '1', 'success' => false, 'error' => '']);
exit;
/***********************************/
}
/* update session activity timestamp */
$_SESSION['ssoLastActivity'] = time();
if (!empty($_SESSION['ssoUser']) && !empty($_SESSION['ssoPassword'])) {
/* already logged in */
return [
$_SESSION['ssoUser'],
$_SESSION['ssoPassword'],
];
}
/* retrieve MySQL login credentials here and store them in $user and $password */
/* $user = ...; $password = ...; */
return [
$user,
$password,
];
}
Has anybody a solution for logout via my SSO script, that leads me to the login page with the message, that the session is expired?
UPDATE:
The issue seems to be connected to my PhpMyAdmin server configuration (/etc/phpMyAdmin/servers.ini.php in my case):
<?php
$cfg['Servers'] = array(
1 => array('auth_type' => 'signon', ..., 'SignonScript' => '/usr/share/phpMyAdmin/sso.php', 'SignonURL' => 'index.php?server=1'),
2 => array('auth_type' => 'cookie', ...)
);
I inspected the network request after my session timeout, and it turns out, that there's actually a request with ?session_expired=1 (which triggers the session timeout message) sent to server 1; because this script is returning null (no login), it redirects to the SignonURL index.php?server=1, omitting the extra session_expired query param.
I could extend this url by &session_expired=1, however this would also trigger the message on regular logout.
I'm open for any ideas to improve the behavior.
Related
how can i supposed to do that? i think i miss some queries . I hope you guys can help me with this. How to prevent user from going back to the login-page after successful login using back button . Because when I login in and pressed back im going back to my login page. Need help everyone. im using laravel framework
public function login(Request $req)
{
$username=$req->input('email');
$password=$req->input('password');
$breadcrumb = 'Dashboard';
$pageTitle = 'CollabUX | Dashboard';
$prepath ='../';
$currentURL = Req::url();
$user = DB::table('add_users')->where(['username'=>$username,'password'=>$password])->get();
if(count($user)>0){
// Store a piece of data in the session...
session(['isloggedin' => 'true']);
return View::make('dashboard')->with(
array('breadcrumb' => $breadcrumb,'pageTitle' => $pageTitle,'currentURL' => $currentURL,'prepath' => $prepath));
}
else{
//imbes na empty page, redirect ka ulit sa login page
$data = array(
'error' => 1,
'remarks' => 'Invalid Username/Password. Please try again.'
);
return View::make('login')->with('data', $data);
}
}
You can do this by using session_start()
On the start of your home page add this line
session_start()
now on you login page do the following
if(isset($_SESSION['user'])){
// redirect user to $_SERVER['HTTP_REFERER']
}
and in your login function after successful login do this
$_SESSION['user'] = //<user name of logged in user>
on logout do this
session_destroy()
$_SESSION array can hold any number of user defined values, you can use this to store all the data related to a session
$_SERVER['HTTP_REFERER'] will take user to the last url, you might want to change it according to your requirements
Simply do check your login session on login form page, if it is true then redirect them to their dashboard.
I'm trying to create a simple to use API with php but I have run into multiple problems. I'm working on an user api that does basic CRUD stuff.
If I do a POST request with cURL to my user api (user.php), a new session id is used during the execution of user.php.
So in order to combat that I tried to send the current session id with the POST request to user.php. The problem I have right now is that after setting the id with session_id($_POST['session']) and then starting my session with session_start() my server will get stuck on executing that code and will eventually throw an Internal Server Error 500.
I tried to get my server to show me what the error is with ini_set('display_errors', 1); and an .htaccess file (content: php_flag display_errors 1) but to no avail, the server just gets stuck.
test.php
<?php
session_start();
// Check for available session
if (!isset($_SESSION['id'])) {
header('location: index.php');
} else {
// Initialize cURL
$curl = curl_init();
// Set parameters for POST request
curl_setopt_array($curl, [
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => 'http://localhost/api/user.php',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => http_build_query([
'session' => session_id(),
'username' => 'testuser',
'password' => 'testalot',
'name' => 'testuser',
'isAdmin' => 0
])
]);
// Execute POST request
$response = curl_exec($curl);
/* <<< Doesn't get beyond this point. */
// Dump JSON
var_dump($response);
// Close cURL session
curl_close($curl);
}
?>
user.php
<?php
// Declare integer checking function
function isInteger($input) {
return ctype_digit(strval($input));
}
// Declare result object
$output = ['success' => false, 'data' => [], 'error' => ''];
// Action on POST
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
// Check if session id was sent
if (!empty($_POST['session'])) {
// Set session id
session_id($_POST['session']);
// Start session with received session id
session_start();
/* <<< Freezes at this point. */
// Check session for available user id
if (isset($_SESSION['id'])) {
// Only admins are allowed to execute POST requests
if ($_SESSION['isAdmin'] == 1) {
// ... more code ...
I'd of course also use a different method of accessing my API that does not require me to send the current session id, if there is any. Any ideas?
UPDATE:
Look #Neok's comment under my question. That is the solution. Just pointing it out for others that might have the same issue.
Make sure that php.ini is set to log all errrors
error_reporting(E_ALL);
or
ini_set('error_reporting', E_ALL);
PHP Documentation says session_id() returns the session id for the current session or the empty string ("") if there is no current session (no current session id exists). So instead of taking $_SESSION['id'], try that:
// Check for available session
if (session_id() == "") {
header('location: index.php');
} else {
...
}
Otherwise your code redirects to index.php in a loop causing error 500.
I have API login using session, when mobile apps use login feature actually they hit the API. In API login, i made session login so when the user login it give response session. check my code below:
public function user_post()
{
$data = array (
'username' => $this->input->get_post('username'),
'password' => sha1($this->input->get_post('password'))
);
$result = $this->login_m->user_check($data);
if ($result ) {
foreach ($result as $row ) {
$sess_array = array(
'username' => $row->username,
'email' => $row->email
);
$this->session->set_userdata('logged', $sess_array);
$this->response(array('success' => $this->session->userdata('logged') ));
}
} else {
$this->response(array(404 => 'missing parameter'));
}
}
and the response will be like this below:
* {
* "success":
* {
* "username": "johndoe123",
* "email": "myemail#my.com"
* }
* }
my question is, how to get the session to validate API post? example:
i have post API to store new data. i've imagine this way would be good, set the param to catch the session name 'logged' using codeigniter , in session 'logged' is already has email and username, so will use it as condition to check to table is the email and username is in the table.
$this->session->has_userdata('logged')
so the mobile apps need to save the session in their apps to send again as params. and the code would be like this below:
$data = array(
'idcardno' => $this->input->get_post('idcardno'),
'dateofbirth' => $this->input->get_post('dateofbirth')
);
$addnewpolis = $this->modelname->modelmethod($data2);
thank you guys,
CMIIW
You cannot use sessions like you want in your code with external api calls. You may generate a token from the login and return it. Then on next api calls from your mobile, send this token in order to know the user identity.
Why: Is it good to implement REST api using Sessions?
To generate a token:
https://www.google.com/search?q=generate%20token%20php&rct=j
Then return it in your response and save it somewhere in order to retrieve it on next calls.
I am building a pretty simple web application. I'm having trouble handling the code return after a user logs in with Instagram. I'm also using another API to assist me you can find it here: https://github.com/cosenary/Instagram-PHP-API.
My homepage logs the user in you can see the php code below
<?php
require 'Instagram.php';
use MetzWeb\Instagram\Instagram;
// initialize class
$instagram = new Instagram(array(
'apiKey' => 'YOUR_APP_KEY',
'apiSecret' => 'YOUR_APP_SECRET',
'apiCallback' => 'YOUR_APP_CALLBACK' // must point to success.php
));
// create login URL
$loginUrl = $instagram->getLoginUrl();
?>
Users are successfully sent to the Instagram login page but when they authorize my app and Instagram responds with a http://your-redirect-uri?code=CODE The next page fails to render.
You can see the code for the "success" page that is supposed to be displayed below.
/**
* Instagram PHP API
*
* #link https://github.com/cosenary/Instagram-PHP-API
* #author Christian Metz
* #since 01.10.2013
*/
require_once 'Instagram.php';
use MetzWeb\Instagram\Instagram;
// initialize class
$instagram = new Instagram(array(
'apiKey' => 'YOUR_APP_KEY',
'apiSecret' => 'YOUR_APP_SECRET',
'apiCallback' => 'YOUR_APP_CALLBACK' // must point to success.php
));
// receive OAuth code parameter
$code = $_GET['code'];
// check whether the user has granted access
if (isset($code)) {
// receive OAuth token object
$data = $instagram->getOAuthToken($code);
$username = $username = $data->user->username;
// store user access token
$instagram->setAccessToken($data);
// now you have access to all authenticated user methods
$result = $instagram->getUserMedia();
} else {
// check whether an error occurred
if (isset($_GET['error'])) {
echo 'An error occurred: ' . $_GET['error_description'];
}
}
?>
If users cancel the authorization request the "success" page properly renders and displays the correct error message. So I believe my issue is in the handling of the code parameter that Instagram returns to my web app. Thanks for the help.
Check that YOUR_APP_CALLBACK redirect url is correct - it should be the same here as it is in your Instagram App. Check out their guidelines for acceptable redirect urls here: http://instagram.com/developer/authentication/
As long as $_GET['code']; is set then the plugin should take care of the rest so I would check that this is being set too.
If you haven't done this already have a look at the plugin example here.
That should get you started.
Could anybody brief about user_token functionality in Auth module? What is a use and how this incorporates in Auth module?
It is used when a user checks the 'Remember me' box on your site. A token is generated for the user and stored in the user_tokens table.
If you look at the Kohana_Auth_ORM class in the _login function, you can see how it is created:
if ($remember === TRUE)
{
// Create a new autologin token
$token = ORM::factory('user_token');
// Set token data
$token->user_id = $user->id;
$token->expires = time() + $this->config['lifetime'];
$token->save();
// Set the autologin cookie
cookie::set('authautologin', $token->token, $this->config['lifetime']);
}
It is used by the auto_login() function also in the Kohana_Auth_ORM class:
/**
* Logs a user in, based on the authautologin cookie.
*
* #return boolean
*/
public function auto_login()
{
if ($token = cookie::get('authautologin'))
{
// Load the token and user
$token = ORM::factory('user_token', array('token' => $token));
if ($token->loaded() AND $token->user->loaded())
{
if ($token->user_agent === sha1(Request::$user_agent))
{
// Save the token to create a new unique token
$token->save();
// Set the new token
cookie::set('authautologin', $token->token, $token->expires - time());
// Complete the login with the found data
$this->complete_login($token->user);
// Automatic login was successful
return TRUE;
}
// Token is invalid
$token->delete();
}
}
return FALSE;
}
It is up to you to correctly use this capability within your authorization controller. I'm relatively new to Kohana, but I perform a simple check to redirect a user if they go to the login form and are already logged in or can automatically login:
if (Auth::instance()->logged_in() || Auth::instance()->auto_login())
Request::instance()->redirect('auth/');
The code for the Auth module isn't too difficult to understand. If you're new to Kohana, it's a good starting point to see how the ORM module works.