用 PHP 设计一个安全的自动登录 cookie 系统

2021-12-21 00:00:00 cookies php setcookie login-script

我想为用户检查自动登录选项.基本上,这意味着 cookie 将存储在客户端.

I want to have an auto login option check for a user. Basically that means a cookie will be stored on the client side.

现在的问题是,如何确保 cookie 不会被欺骗/修改.

Now the question is, how do I make it secure so the cookie will can not be spoofed/modified.

我的一个朋友建议使用一个 db 表来存储 session_id、用户的 ip、浏览器信息等,然后在用户再次访问该网站时比较所有这些信息.

One of my friends suggest having a db table that stores the session_id, user's ip, browser info, etc and then compare it all that information once a user goes to the website again.

我觉得有一个单独的桌子有点太麻烦了.还有另一种方法吗?也许带有令牌或类似的东西?

I feel like having a separate table for that is a bit too much trouble. Is there another way to do it? Maybe with tokens or something like that?

推荐答案

你想要这个臭名昭著的 cookie 越安全,它就越麻烦.如果您的用户应该特别安全,您将不得不采用最麻烦的方法.

The more secure you want this infamous cookie, the more trouble it's going to be for you. If your users should be particularly secure, you will have to go with the most troublesome approach.

如果您想尽可能安全,您应该只接受带有 https 的 cookie.如果 cookie 通过 http 被接受,它可以被嗅探和窃取.

You should only accept this cookie with https if you want to be as secure as possible. If the cookie is accepted over http, it can be sniffed and stolen.

我建议 cookie 根本没有用户数据(如您所建议的令牌).不幸的是,这将需要另一个表.当用户登录并选择保持登录"时,在此表中创建一个条目.该条目可以是任何无意义的值(例如 md5(uniqid('', true));.此令牌在数据库中可以是唯一的并映射到用户 ID.

I would recommend that the cookie have no user data at all (a token, as you suggested). This will, unfortunately, require another table. When a user logs in and chooses "keep login," create an entry in this table. The entry can be any meaningless value (such as md5(uniqid('', true));. This token can be unique in the DB and mapped to a user's ID.

当用户访问您的网站时,您可以检查该 cookie 的值并获取它所属的用户并登录.此时,您销毁旧令牌并创建一个新令牌.破坏"可以意味着很多事情.您可以将其从数据库中完全删除,也可以设置一个禁用令牌的标志.您可能希望允许多次使用相同的令牌,以防收到 cookie 但由于某种原因无法通过身份验证,但我认为这是不安全的.您可能还想存储令牌的时间戳,并且只有在某个有限的时间段内(例如 30 天)才接受它.

When a user visits your website, you can check the value of that cookie and get the user it belongs to and log them in. At this point, you destroy the old token and create a new one. "Destroy" can mean many things. You can delete it from the DB entirely or have a flag that disables the token. You may want to allow the same token to be used multiple times in case the cookie is received but the authentication doesn't go through for some reason, but I think this is insecure. You may also want to store the timestamp of the token and only accept it if it's been some limited period of time (30 days for example).

正如您的朋友所指出的,您可以存储其他信息,例如用户代理、IP 地址等,但即使使用相同的浏览器(尤其是移动浏览器)并且如果不接受用户的持续登录,这些信息也可能会发生变化因此,这可能会给他们带来不和谐和不便.

As your friend points out, you can store other information such as user agent, IP address, etc., but these may change even with the same browser being used (especially with mobile) and if a user's persistent login is not accepted because of this, it could be jarring and inconvenient to them.

如果你真的不想创建另一个表,那么你将不得不通过存储某种方式从 cookie 值中获取用户的 ID.这不太安全.

If you really don't want to create another table, then you will have to store some way to acquire the user's ID from the cookie value. This is less secure.

相关文章