logout a user when the user faces unusual thing - php

is there any way to logout a user in yii2 advanced, when the user faces unusual thing(like shut down his/her computer when the user works with his/her account).
default of yii2:when you are login and your computer goes into shut down,when you start up for another time and go to your account ,you are in login state but your session ID will change.
i want to logout the user or at least the session id never change.

Maybe you want to disable enableAutoLogin parameter for User class, so that when user closes browser or shutdowns/restarts a computer, he will have to enter login data again.
This kind of behavior is often used in banking systems (at least in my country) for security reasons.
If that is what you are looking for, then this setting can be configured in frontend/config/main.php file
'components' => [
..
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => false,
..
],

If a user restarts their computer, the browser session cookies that are there will remain in place until they expire or the user chooses to delete them/clear data from their browser cache. By definition, if the user remains logged in, their session has been preserved. This has nothing to do with whether a client computer has been restarted or any other change of state on a client machine - your website is agnostic to this, i.e. it does not have any mechanism to know of this particular change in state and neither should it care.
If you wish to logout a user programatically, you can use this code for the native Yii2 user application component in your controller:
Yii::$app->user->logout();

Related

CakePHP 3 - login through non-Cake subdomain

I'm re-building a web application in CakePHP 3 and plan to change how the application is structured. At the moment the architecture is as follows - and none of it is written in Cake.
There is a login page at https://app.example.com which sets PHP session variables on successful login. All of the applications are then in sub-directories, e.g.
https://app.example.com/application-1
https://app.example.com/application-2
https://app.example.com/application-3
Each sub-directory has a script which checks the appropriate session vars are set, otherwise redirects to the login page, e.g. trying to access https://app.example.com/application-1 without being logged in sends the user to https://app.example.com/
I'm planning to rebuild one of the applications, https://app.example.com/application-2 in CakePHP 3, and do so on a separate subdomain (e.g. https://cake.example.com/).
What I want to do is allow the users to still login through https://app.example.com and then use https://cake.example.com/ if they are succesfully authenticated.
I was planning to allow my PHP sessions to work across multiple subdomains - as per Allow php sessions to carry over to subdomains
I'm not sure though how this would work within Cake 3 though. One idea I had was to set up https://cake.example.com/ without any of Cake's Auth functionality enabled. I was then going to use the AppController::beforeFilter() to check the session variables. If they were set appropriately, allow the user to use any Cake Controller method. If not, redirect them to https://app.example.com where they can login.
I was looking for some advice on whether there is a better way to do this, and if this is secure? I'm aware that doing this is essentially like developing the Cake app with no authentication, and just relying on the session vars being read in beforeFilter().
The login script at https://app.example.com also writes to a database where we have things such as the user ID, IP, user agent string and date/time. I can access this DB from my Cake application, but the idea of querying this database on every single request also seems wrong.
It's worth mentioning that https://cake.example.com cannot have it's own login page, even if it connected to the existing users database to lookup the credentials. This is because the users login through https://app.example.com which then acts as a dashboard for their applications. Essentially by the time they get to https://cake.example.com they either have to be authenticated, or sent back to the existing login page.
Checking the session manually can be just as secure as using CakePHPs auth component, as the component does exactly the same (given that you'd be using the session storage), just with data that you've set via AuthComponent::setUser(), ie it all depends on whether you implement things properly.
Checking the session value in AppController::beforeFilter(), and redirecting if necceesary should generally be fine, and as mentioned is pretty much the same as what the auth component does internally, it will check whether the configured session key is present and not empty.
You could possibly still leverage the CakePHP auth functionality if you wanted to, the flat u_id value in the session should suffice. For the auth component, just configure the login/logout options and the session storage key accordingly, ie if your login page is at https://app.example.com, and your login app writes auth data to $_SESSION['u_id'], configure the auth component like this:
$loginUrl = 'https://app.example.com';
$this->loadComponent('Auth', [
'loginAction' => $loginUrl,
'loginRedirect' => $loginUrl,
'logoutRedirect' => $loginUrl,
'storage' => [
'class' => 'Session',
'key' => 'u_id'
]
]);
That should be all that is needed (authentication wise), the component should pick up the possibly existing session key and treat you as authenticated, or otherwise redirect to https://app.example.com. Defining loginAction will prevent the component from whitelisting a controller/action, and logoutRedirect will be returned by AuthComponent::logout(), so you could easily implement a standard logout action in your CakePHP app if you want/need.
Of course this all depends on the u_id session value being accessible (ie you've configured your CakePHP app to pick up the existing session) and reliable in the first place.

Laravel - Login to only one browser at a time

I am building a simple log in app and I want to allow users to login from one browser at a time.
In other words, if users are logged in in Safari, and then open a Firefox browser and login into the app, Safari app should log them out. Likewise, if users then try to login again into Safari, Firefox app should kick them out. Can some one help me in this. Currently I am using Laravel's out of the box login module to make development fast by using command PHP ARTISAN MAKE:AUTH.
Kindly guide me.
How I would do it: I would consider adding a 'user_agent' column to the 'users' table in your database, in which you can record the browser type each time a user logs in (using $_SERVER['HTTP_USER_AGENT'] or the like...). Once that's in place, you can add a Middleware that will compare the stored user agent against the current user agent and initiate a logout if the two don't match.
However, this will only log the user out of the Safari browser once they have logged into the Firefox browser and then they try to go back to Safari. If you need the Safari browser to logout immediately as soon as the user logs into a different browser, you can simply add an ajax polling function that will trigger the Middleware even when the user is not actively using the site (and this way the Safari browser will logout as soon as the user logs into Firefox etc).
Again, I'm sure there are many ways to butter this slice of toast, these are just my initial thoughts...
It's pretty simple – when you log users in (most probably postLogin() method of your AuthController), in case of success - store the current session ID in the database, in User model. Then, in your 'auth' middleware, add an extra check – compare user's session ID from the model with PHP session ID. User will be kicked out in other browsers or sessions upon next click.
Steps in more detail:
Add a migration that adds a current_session field to User table.
Persist current session ID in postLogin()
Compare session ID from the database with PHP session ID. Optionally, destroy the session in case of mismatch

How prevent destroy of specific session

I use Yii2 framework for my current project. My problem is when the user logs out all the sessions are destroyed but on the frontend I have a session registered which needs to be there after the logout process.
Is there a way in PHP to store that one session?
You probably will need to actually create 2 separate sessions. For this I would think the advanced template would be the best starting point. Frontend would be your main site, and backend would be your logged in area. You could even make a 3rd for your admin panel, if needed.
In your config you would need to specify different sessions. The way I use it, is to completely separate my frontend from the backend.
Example of config;
'components' => [
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
'identityCookie' => [
'name' => '_frontendUser', // unique for frontend
]
],
'session' => [
'name' => 'PHPFRONTSESSID',
'savePath' => sys_get_temp_dir(),
],
....
You would do the same for backend, only using different names.
If they can still go to the main site while they are logged in, you would need to do some addition checks, like checking if the other session exists. You could make a special rule to redirect them off the main site to the logged in area if it exists. If they still need to access the main site but know if they are logged in (like to show logout instead of login link, or show their username) then you would have to reference the other session.
I am not sure if you can actually use a session from another section... A way around it would be to store data in the first session about the 2nd session. In your login routine, you would need to inject the user data into the first session. And on logout, remove it.
Not sure what our going for, and there are still some things to look into (like if you can access another session without hacky options).
However, I think your hangup right now is that you need to define separate session values in your config.
I should also add, I wrote a wiki about how to have 2 separate sessions here: http://www.yiiframework.com/wiki/814/guide-how-to-actually-separate-frontend-user-and-backend-admin-on-yii2-advanced/
Problem with yiii2 advanced, is by default if you login to the frontend you are also logged into the backend. Well if you use frontend as members and backend as admin, you dont want it like that! A member shouldn't be logged into the admin area. So you have to make them 2 separate sessions.
While my wiki is for a slightly different use, I think it stems from the same problem and may help you figure this out.
If you need different sessions for frontend / backend, separate it as pointed in other responses but, if you need to save data between user sessions, save it to the database.

Yii always starts a session when I touch CWebUser

I'm developing a RESTful API server which require on some of its API methods a valid session, indicated in the form of a cookie with a session ID.
I'm using Yii v1.1.15 with stock PHP session handler (probably 'files').
Thing is that on every call to CWebUser it creates a session and I don't want this. A session should exists only when I explicitly create it, meaning on login (or register which auto-logins the users). For example, if in a certain API method I check if the user is guest using a construct which involves:
Yii::app()->user->isGuest
it automatically creates a session since this code is given in CWebUser.init().
Now, I'm not in a hurry to change CWebUser (in fact, to change this in the already extending class which altered it slightly, in other aspects) since I'm afraid this will have un-anticipated impact on the system.
Can anyone enlight me on this?
What would you do?
Thanks!
Environment:
// Yii v1.1.15
// session component configuration: (but believe me, I've tried every
// combination - its not really related. Check CWebUser.init()...)
'session' => array(
'class' => 'CHttpSession',
'autoStart' => false,
'sessionName' => 'MY_COOKIE_NAME',
'cookieMode' => 'allow',
'cookieParams' => ['lifetime' => 1000],
'gcProbability' => 33,
'timeout' => 1000,
'savePath' => '/tmp/',
),
// Web User's _allowAutoLogin_ is set on 'false'
So you need to check if a user is logged in (This is why you use isGuest) but you don't want to use a session?
The method isGuest uses a session variable to check if an user is logged in. The session is opened when the CWebUser is created. (in the init method like you said.) The isGuest is part of the CWebUser class. If you want to call this method it will always create a session. Unless you overwrite it.
I think you can go 2 ways at this:
Open a session, check if a user is logged in (isGuest) and then close it only if the user is not logged in. You will need to overwrite the isGuest method. Overwrite any other methods to open a session when you need it. (login/register)
Let the client send its login data on every request so you dont have to check the session and thus don't have to open it.
In both cases you will need to overwrite the CWebUser.init() so it won't open a session whenever the CWebUser is created.
So basically this was all a need that came from the following requirement set:
Yii will be used (also) as a RESTful API server.
The RESTful server will establish session only after successful login.
The above last point implies that there is no session cookie for guest users but rather it exists only for an authenticated user session.
The advantages of the above? mostly the 'free' management of login sessions by the stock PHP session including timeouts, garbage collection etc.
Despite the initial appealing of this design, the drawback overcame the advantages:
Indeed, isGuest is a property of CWebUser that when tested, already implied a session generated for the request.
Trying to change the above behavior introduced lots of issues and bugs, and god knows what lurked ahead. In essence, trying to change this behavior on Yii v1.1.x was too problematic as lots of built in features and behaviors (in the abstract meaning...) of Yii based app are implicitly using an established session.
So, I reverted to the following design:
Yii's session management was reverted to stock - yes please! open a session for everything going on! (just do it well as you normally do).
The RESTful server sends an explicit session token on successful login calls.
The client needs to save this token and send it explicitly with every API method that requires an authenticated session.
Server side saves the session token in the "freely managed" (PHP) session and thus is able to verify on each distinct request that the token for the user with this PHP session is indeed his, and is valid.

php an user should login in one system and should not be able to login from other system unless requested

I want to allow users to use only one system to login.
if they use another machine then they should not be able to login.
If they want to login then they can click request login option which will sent a reset link to the users email which when clicked will reset and update the database so that from now on he can login form that machine form which he made the reset request.
so, when ever the user changes his machine he should not be able to login and can request a reset option.
i am using ip and session id and previous session id to check login from one machine.
if his session expires in that machine he will be logged in next time by storing the previous session id reference in a cookie.
so each time he access there will be two cookies to mean that whether he previously logged in this machine and if so then the session id is updated and he is logged in.
so if he is login in from a machine and if there is no previous/current session-id/ip-address then he is considered totally new to that machine and he cannot login.
Hope i have made it clear. if it is not much clear then please comment then i will edit my question.
I want a better approach or some other efficient mechanism to implement such functionality.
Even if the client is in a lan all the above conditions apply.
do my way of doing this has complications? if so then please suggest a good one.
Thank you.
Editing after a comment from https://stackoverflow.com/users/164394/purplepilot
the user can login anywhere but if the machine changes they can request an reset through their email. when they click the link in the email then that machines ip will be recorded and the user will have to continue in that system. This was requested by the admin cause there is going to be only two admin users.
Why dont you use cookie instead of session as your app demand that.
i think you are confused
Session never stored in client , cookie does. so you have to think about cookie for this app. Logic for the project seems okey once you implement cookie instead of session.

Categories