Session created and deleted with a delay : Android webView - yii2

My website uses Yii2 as a framework, there I used “Dektrium user” module to implement registration and auth. In config, I set autologin property to “true”
When I registered on my site (opened via webView), the session is opened, I stay logged in, and it’s ok, but when I close my app and open it again - I see login form and I need to enter my registration data again. But, If I wait (about 30 sec - 1 minute) and then close the app - session will be saved and I can open the app again and use without entering my login and pass.
The same situation related with log out: if I click to “log out” and quite quickly close webView app, and then open again - I am still logged in.
The most strange part is that in iPhone webView all working fine. Of course, I tried to reproduce this bug via browser, without webView - and they're all working fine too.
Maybe anyone has some ideas, why webView can “freeze” session with some delay?

About login()
If $enableSession is true:
the identity information will be stored in the session and be available in
the next requests
in case of $duration == 0: as long as the session
remains active or till the user closes the browser
in case of $duration > 0: as long as the session remains active or as long ? as the
cookie remains valid by it's $duration in seconds when
$enableAutoLogin is set true.
You need to use the second parameter for the Yii::$app->user->login(); which defines what number of seconds that the user can remain in logged-in status, defaults to 0.
//keep the cookie duration valid for 120 seconds or 2 minutes
Yii::$app->user->login($user,120);
As you have set the $enableAutoLogin to true so this parameter is not being ignored and the default value of 0 is used and the session is cleared as soon as you close the app. See the DOCS for more details.
For Dektrium-user you are using the value is set in the module's LoginForm model on top it uses the rememberMe property
Yii::$app->getUser()->login($this->user, $this->rememberMe ? $this->module->rememberFor : 0);
which defaults to false and works with the checkbox on the login form for this property to be set to true
/** #var string Whether to remember the user */
public $rememberMe = false;
So that means if you are not using the rememberMe checkbox on the login form to login the session and cookie will remain valid for 0 seconds as soon logged out or window closed.
You can set the else part value from 0 to any custom like 60 for 1 minute
Yii::$app->getUser()->login($this->user, $this->rememberMe ? $this->module->rememberFor : 60);
OR (I don't like this part thou)
You can set public $rememberMe=true; by default so that it always passes the default value of two weeks to be remembered if not logged out.
You can configure a custom value in the module settings in the config under modules too if you don't want the default rememberFor value (2 weeks).
'components'=>[
'user'=>[
'rememberFor'=>3000,

Related

Infinite Redirect Loop on Google One Tap Signin

I'm having trouble finding any documentation in regards to Google One Tap UX and how to persist signin state after a signin redirect. I am using the html api, check the code here:
setTimeout(function () {
let target = document.getElementById('google-signin');
target.innerHTML = '<div id="g_id_onload" data-client_id="x" data-context="signin" data-login_uri="https://x/account/google/callback" data-auto_select="true" data-itp_support="true"></div>';
var s = document.createElement("script");
s.src = 'https://accounts.google.com/gsi/client';
document.head.appendChild(s);
console.log('appended script', s);
}, 30000);
</script>
Essentially I am delaying this signin popup for 30 seconds, that part works fine but soon after this is what happens:
Sign in occurs
Redirect happens
Server redirects back to the referer page
After 30 seconds the process starts again
I would have assumed the google sdk would set a cookie or something somewhere but I guess it does not, either that I'm supposed to handle persisting signin state through my own means. I just want to know the correct approach here.
My question is: How does google know if a user has already signed in using Google One Tap UX?
Figured out a solution. Google allows you to put a property on your div tag called data-skip_prompt_cookie="yourcookie" this will skip the one tap prompt if that cookie is present with a truthy value.
What I did was on my server callback in asp.net I added a cookie to the response. This ensures the prompt is only disabled once someone actually signs in.
Response.Cookies.Append(
"yourcookie", "true");
This ensures when my server redirects back to the originating page, the cookie exists and the one tap does not show up again

New session entries are being created in database even when codeigniter session library is not loaded. Why?

I am having a rather weird problem with Chris Kacerguis’ CodeIgniter REST Server.
Problems:
1) I am NOT loading the CodeIgniter session library, even then new entries are being created in the ci_sessions database table, everytime I am making an HTTP Request to my REST Api.
2) A brand new entry is being created (and the old entry is NOT being updated) in the db, on every HTTP Request, even when the IP Address is remaining the same.
This is my config.php file:
$config['sess_driver'] = 'database';
$config['sess_cookie_name'] = 'ci_session';
$config['sess_expiration'] = 0;
$config['sess_save_path'] = 'ci_sessions';
$config['sess_match_ip'] = TRUE;
$config['sess_time_to_update'] = 300;
$config['sess_regenerate_destroy'] = TRUE;
$config['cookie_prefix'] = '';
$config['cookie_domain'] = '';
$config['cookie_path'] = '/';
$config['cookie_secure'] = FALSE;
$config['cookie_httponly'] = FALSE;
I tried, individually and in combination, the following things:
$config['sess_match_ip'] = FALSE;
$config['sess_time_to_update'] = 0;
$config['sess_regenerate_destroy'] = FALSE;
and
$config['cookie_domain'] = '.mydomain.com';
But nothing worked.
Is this normal or some kind of a bug? What am I doing wrong? Anyone else having the same problem?
Another thing is that, I am not facing this issue in vanilla CodeIgniter. There, everything is working fine and as expected.
Update
I found something while struggling with the second part of the problem.
Two session entries are being created in the database while making the first HTTP Request - one for the client and another one for the REST Server. From the second request, the client 'version' of the cookie is being UPDATED while the server 'version' is being RE-GENERATED.
For the 1st part of the problem:
As pointed out by #JamesLalor in the comments,
You must either be autoloading the session
OR
You are using some external library which is, in turn, loading the session library.
For the 2nd part of the problem:
The below solution may not be the best, but it worked for me.
Multiple sessions creation problem occurs when:
You have both REST Server and Client within the same CodeIgniter Application directory
AND
Session library is auto-loaded
To the Client, the user is the consumer. A session is created for the user, having the IP address of that user. A cookie is set on the user’s browser with which the session is validated and updated (or newly created) based on the validation.
To the REST Server, the Client is the consumer. Here also a session is created (if both condition 1 and 2 above is fulfilled), but this time, it is for the Client, and this session has the IP address of the server on which the Client resides (if condition 1 above is fulfilled, then it is the IP address of the same server on which your app resides). But this time a cookie could not be set, as the consumer is not a browser. Hence, the session validation fails and a new session is created each time the page loads.
Solution:
REST is stateless and every request should contain all the information required to fulfil the request. Therefore, using sessions (whose sole job is to maintain user’s state) on REST Server is considered a bad practice. It is the job of the Client to maintain the user’s session and pass the required information to the REST Server on each and every request.
Therefore, assuming that you would not be needing session within REST Server, the solution is to remove session from autoload[‘libraries’] list, within autoload.php file, and load the library within the Client constructor (or when you need it).
Sorry for grammatical errors and/or bad English. It is not my native language.

Html - single page - staying logged in

I have an Html page with a load of javascript that changes between views.
Some views require the person to be logged in, and consequently prompt for it.
How can I note the person has successfully logged in, using the javascript, that will not be a security issue, but will mean the person does not have to repeatedly log in for each view. I do not want to keep on going back to the server each time.
Edit:::
To explain more. Here are the problems I see.
Lets say I have the following in my javascript:
var isLoggedIn = true;
var userEmail = "myemail#mysite.com";
Anyone can hack my code to change these values and then get another person's info. That is not good. So instead of isLoggedIn do I need something like a hashed password stored in the javascript:
var userHashedPassword = "shfasjfhajshfalshfla";
But every where I read, they say you should not keep any password stuff in memory for any length of time.
So what variables do I keep and where? The user will be constantly flicking between non-user specific divs and user-based divs, and I do not want them to have to constantly log in each time.
****Edit 2:*****
This is what I am presently doing, but am not happy with.
There is a page/div with 3 radio buttons. Vacant games (does not require user information), My Game (requires knowledge of user and must be signed in), My Old Games (also requires logged in status).
When first going on the page it defaults on vacant games, and gets the info from the server, which does not require login.
In two variables in the javascript I have
var g_Email = "";
var g_PasswordEncrypted = "";
Note these are both 0 length strings.
If the user wants to view their games, they click the My Games radio button. The code checks to see if the g_Email and PasswordEncrypted are 0 length strings, if they are it goes to a div where they need to login.
When the user submits their loging info, it goes to the server, checks their details, and sends back an ok message, and all the info (My Games) that the user was requesting.
So if the login was a success, then
g_Email = "myemail#mysite.com";
g_PasswordEncrypted = "this is and encrypted version of the password";
If there is any failure in login, these two are instead set to "".
Then when the user navigates to any page that requires login, it checks to see if these two strings are filled. If they are, it will not go to a login page when you request information like My Games.
Instead it just sends the info in these strings to the server, along with the My Games request. The server still checks these Email and encrypted password are valid before sending back the info, but at the client side, the user has not had to repeatedly input this info each time.
If there is any failure in the server request, it just sends back an error message (I am using ajax) in the callback function, which knows to set the g_Email and g_PasswordEncrypted to "" if there is anything wrong. (In the latter case, the client side knows it has to re-request the login details because these two strings are "").
The thing I do not like is I am keeping the Encryted password on the person's client machine. If they walk away from their machine, someone can open up the debugger in something like chrome and extract these details, and then hack it into their machine some time later.
If javascript loads content for each view from the server then it is for server to know if a current session belongs to logged user or not. In case the user is not logged, the server responses with prompt to login, otherwise it sends content of the view.
If javascript bulds content for the views deriving it from the data that was already received from the server then it should use some variable keeping state of the user (logged/not_logged). And depending on that value javascript will either show a prompt to login or display required content of the view.

Use the chrome.idle API to restart application

I have a Chrome kiosk app that basically just uses webview to allow someone to browse through a catalog.
I found the chrome.idle API, and believe I understand how to set idle time and query if the device is idle, but can I have it restart the application when the state changes to idle or at least navigate back to a set URL?
The end goal is to have the catalog reset itself for the next user after being left idle for a set period of time.
https://developer.chrome.com/apps/idle
Well, the documentation is pretty clear..
First, you need to declare in the manifest that you want to use this API, as it needs a permission.
"permissions" : ["idle"],
You could go with a poll-based approach as you suggested, but why? There's an event provided. So, we go on to use that.
You need to inform Chrome how long an interval without user input you consider an idle state.
chrome.idle.setDetectionInterval(120); // 120 seconds
Lastly, you need to react to a change to an idle state.
chrome.idle.onStateChanged.addListener(function(newState) {
if(newState == "idle") {
// Reset the state as you wish
}
});

Oracle APEX - HTML Links Breaks Session and Requires New Login

Ok so here is what is happening:
I have a client that I am building an application for. My client has a flowchart that they would like posted on the front page of their application. Check. My client then wants this flowchart to be set up as an image map so that a user could click one of the boxes in this flowchart and be taken to a report in another part of the application. Check.
All of that is elementary and, in a technical sense, works. The issue is, and it is an issue I have encountered before with APEX, is that every time a user clicks one of these links it takes them to the login screen. It seems that linking directly to a page's URL breaks the session and requires you to login again, even if you are linking from one page in the application to another in the same application.
I have played with all of the authentication settings in a hopes of fixing this and tried to determine what is breaking the session exactly but with no luck.
Has anyone else had this problem and could share their method for fixing it? I really cant have users logging in every time they click a link and I also cannot simply remove the authentication on the pages. Thanks in advance.
You should pass on the session id in your links. If you don't, then apex will see this as a new session. You can tell from the url: take note of the session id in your url when you are on your image map. When you select an application, take another look at the session id part in the url. If they are different, then you are starting a new session each time.
/apex/f?p=190:90:1674713700462259:::::
190 -> application id
90 -> page id
1674713700462259 -> Session id
To pass on the session, it depends where you construct your links.
In PLSQL, you can find it through :SESSION or :APP_SESSION
For example, in a plsql dynamic region: htp.p('the session id is '||:SESSION);
In javascript code you can use $v("pInstance") to retrieve the value dynamically, or use &APP_SESSION. which will have the value substituted at runtime.
Small example:
function printsome(){
var d = $("<div></div>");
d.text('&APP_SESSION. = ' + $v("pInstance"));
$("body").append(d);
};
So you probably just need to alter the construction of your link somewhat to include the session!
I was assuming the binding variables will do the job. But they were helpless.
Best way is to pass the current session id to an item then use the item value in the link.
f?p=&APP_ID.:32:&P31_SESSION.:::P32_CUSTOMER_ID:#CUSTOMER_ID#