PHP /SESSION:每个用户登录一个?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3643591/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:32:18  来源:igfitidea点击:

PHP /SESSION: Login one per user?

php

提问by Karem

How can i do so only 1 can be online for the 1 user at the time? Idea ?

我怎么能这样做,当时只有 1 个用户可以在线?主意 ?

So you e.g can not login to User1 on one pc/browser and then on the other pc/browser login to User1?

例如,您无法在一台电脑/浏览器上登录到 User1,然后在另一台电脑/浏览器上登录到 User1?

I have my communitysystem in PHP, and it stores in sessions..

我在 PHP 中有我的社区系统,它存储在会话中..

采纳答案by cHao

You could store the session ID (and last access time) in a database, and reject login attempts for users with different session IDs if the last-access time is too recent(say, within the past 20 minutes). Clear the ID on logout, of course.

您可以将会话 ID(和上次访问时间)存储在数据库中,如果上次访问时间太近(例如,在过去 20 分钟内),则拒绝具有不同会话 ID 的用户的登录尝试。当然,在注销时清除 ID。

Note, though, if a user closes their browser without logging out and then reopens it, they may well be locked out for a while (the 20 minutes above, or whatever interval you decide on), since they won't have the matching session cookie anymore.

但是请注意,如果用户在没有注销的情况下关闭浏览器然后重新打开它,他们很可能会被锁定一段时间(上面的 20 分钟,或者您决定的任何时间间隔),因为他们不会有匹配的会话饼干了。

回答by aularon

I assume you save users in a database, add an active_sessionfield, update it upon login, and check it on requests to ensure that current user session id matches the last one stored in the database.

我假设您将用户保存在数据库中,添加一个active_session字段,在登录时更新它,并在请求时检查它以确保当前用户会话 ID 与存储在数据库中的最后一个匹配。

On Login:

登录时:

UPDATE `users` SET `active_session`='$session_id';

When user goes to a page that requires login, you search that value:

当用户转到需要登录的页面时,您可以搜索该值:

SELECT * FROM users WHERE `active_session`='$session_id';

this way, if the user signs in other place, the previous session key gets overwriten, and the SELECT above returns an empty resultset.

这样,如果用户在其他地方登录,先前的会话密钥将被覆盖,并且上面的 SELECT 返回一个空的结果集。

回答by shamittomar

No need to use sessions. Just make a column in your database userstable whether a user is logged in or not. Check it from there.

无需使用会话。users无论用户是否登录,只需在数据库表中创建一列。从那里检查它。

The column can be named LoggedInand can be a enum ('Yes','No'). Also, store the time of last login in some column LastLoggedInSo, when a user wants to login, first check:

该列可以命名LoggedIn并且可以是enum ('Yes','No'). 另外,将上次登录的时间存储在某个列中LastLoggedIn所以,当用户想要登录时,首先检查:

select 1 from users where ID = {$UserID} and `LoggedIn` = 'No'

If a row is returned, let him/her login.

如果返回一行,让他/她登录。

If someone forgets to logout:

如果有人忘记注销:

Run a cron job or script that would reset the LoggedInstatus after a set period of time of users which are logged in for longer than few hours by checking LastLoggedIntime.

运行一个 cron 作业或脚本,该脚本将LoggedIn在通过检查LastLoggedIn时间登录超过几个小时的用户的设定时间段后重置状态。

回答by Bamidele B. Adetayo

Just for anyone who might need this in the future.

仅适用于将来可能需要此功能的任何人。

When a user creates a session or logs in you could take the session id that it generates and store it into a column in your database under that user's account. Then on each page on your application do a check to see if the current Session ID matches the one stored in the database for that user. If not, kill the current session and redirect them to a sign in page.

当用户创建会话或登录时,您可以获取它生成的会话 ID,并将其存储到该用户帐户下的数据库列中。然后在您的应用程序的每个页面上检查当前会话 ID 是否与为该用户存储在数据库中的会话 ID 匹配。如果没有,请终止当前会话并将它们重定向到登录页面。

That way, the session id will be different on each device they are using to login.

这样,他们用来登录的每个设备上的会话 ID 都会不同。

回答by Kai Pommerenke

This solution doesn't require you to access the database on every page and doesn't lock out the user after they failed to log out.

此解决方案不需要您在每个页面上访问数据库,并且不会在用户注销失败后将其锁定。

Add a field for sessionID to your user table in the database.

将 sessionID 字段添加到数据库中的用户表中。

Set the default session handler before calling session_start():

在调用 session_start() 之前设置默认会话处理程序:

session_set_save_handler(new \SessionHandler());

On every successful login, retrieve the stored $sessionID from the database. Destroy the old session with:

每次成功登录时,从数据库中检索存储的 $sessionID。使用以下命令销毁旧会话:

(new \SessionHandler())->destroy($sessionID);

Get the new session ID with:

使用以下命令获取新会话 ID:

$sessionID = session_id();

Store the new session ID to the database.

将新会话 ID 存储到数据库中。

回答by user2005637

The best way to do this is to create an extra column in your users table which is set at 0(false) by default and when logged in set to 1 (true). Then when the user logs out reset to 0. Run a check every couple hours which requires a user to click yes to continue with the session or be auto logged out after a count down timer reaches zero. The floor here is that the longer you leave it until you run your check the longer a user would have to wait to be able to login again if they left your site and came straight back without logging out properly as the user table would still be true until logged out. The side effect is asking for user input more often against losing access for a greater length of time. It needs to be weighed up so that it's not annoying for the user. You could detect that the user has left your site using js and then log out but the user can switch this off and therefore is unreliable.

最好的方法是在用户表中创建一个额外的列,默认设置为 0(false),登录时设置为 1(true)。然后当用户注销时重置为 0。每隔几个小时运行一次检查,这需要用户单击是继续会话或在倒数计时器达到零后自动注销。这里的地板是,您离开它直到您运行检查的时间越长,如果用户离开您的站点并直接返回而没有正确注销,则用户必须等待能够再次登录的时间越长,因为用户表仍然是真实的直到退出。副作用是更频繁地要求用户输入,以免在更长的时间内失去访问权限。需要对其进行权衡,以免对用户造成困扰。

回答by Trond

I sort of have the same task where I only want the user to have one session only. This so it can only be he/she who uses the account, and not a whole lot of other people.

我有同样的任务,我只希望用户只有一个会话。这样只能是他/她使用该帐户,而不是很多其他人。

The way I have designed it is that I have one table where I am storing start and end of session. This to be used for the user to see how long the last visit took and when he/she was last online.

我设计它的方式是我有一张表,用于存储会话的开始和结束。这将用于用户查看上次访问花费了多长时间以及他/她上次在线的时间。

Then I have designed a session-table where I am updating the time/date whenever the user does something. If the time here is older than 30-60 minutes (haven't decided the span yet), the session value will be removed. This so the user can log in again later if he decides to do so. But not within the 30-60 timespan lock.

然后我设计了一个会话表,每当用户做某事时我都会更新时间/日期。如果这里的时间早于 30-60 分钟(还没有决定跨度),会话值将被删除。这样,如果用户决定这样做,他就可以稍后再次登录。但不在 30-60 时间跨度锁定内。

The session-table will be traced by a cron job.

会话表将由 cron 作业跟踪。

回答by Ravi Kant Pathak

My Idea Would be continue from here the first answer I have seen :

我的想法将从这里继续我看到的第一个答案:

You could store the session ID (and last access time) in a database, and reject login attempts for users with different session IDs if the last-access time is too recent(say, within the past 20 minutes). Clear the ID on logout, of course.

您可以将会话 ID(和上次访问时间)存储在数据库中,如果上次访问时间太近(例如,在过去 20 分钟内),则拒绝具有不同会话 ID 的用户的登录尝试。当然,在注销时清除 ID。

Create a column current _session in database , when users loggeed in save the current session in table here we assume that we have a login time is set for 20 minutes and user after login closes his browser and again came back in next 10 minutes ,so here we have his old session set which is valid for 20 minutes , but in actual last time he closed the browser so this time he will have a new session id , so we will catch this session mismatch and here will ask user to login again by deleting the old record we have kept.

在数据库中创建一个列 current _session ,当用户登录时将当前会话保存在表中,我们假设我们将登录时间设置为 20 分钟,登录后用户关闭浏览器并在接下来的 10 分钟内再次返回,所以在这里我们有他的旧会话集,有效期为 20 分钟,但实际上他上次关闭了浏览器,所以这次他将有一个新的会话 ID,因此我们将捕获此会话不匹配,这里将要求用户通过删除重新登录我们保留的旧记录。