PHP 登录中 Session 和 Cookie 问题...

2015-08-16 18:14:37 +08:00
 zeacev

Web新手,最近想写一个完整的博客系统练练手,登录认证这一块有些地方思路不是很清晰,请教一下大家。

首先,单独的Session和Cookie我思路很清晰,但是两者结合再加上数据库后,思路就不怎么清晰了。出于安全考虑,各位在开发的时候,在本地Cookie会放一些什么内容?本地的Cookie内容是怎么和服务器上的Session打交道?希望各位不吝赐教。

然后,有没有必要在user表中增加一个字段比如说叫做AuthCode,再浏览器POST过来的username和password去数据库对比成功之后,将这个AuthCode写到Cookie去,下次浏览器发送请求的时候直接对比username和AuthCode就行了?

其次,我看了WordPress和Typecho的数据库表结构,里面没有类似于AuthCode的字段,但是登录之后却会有这么一个类似于AuthCode的Cookie值,比如说下图Typecho的:

网上那些教程都只简单的说了下到本地设置个Cookie就行了,这样真的安全?

处理登录的时候,各位是怎么在程序中实现的?能否说一下大致思路?

感谢各位的解答

5201 次点击
所在节点    PHP
39 条回复
zeacev
2015-08-17 13:40:31 +08:00
@ferock 这里说的安全不是传输安全,
abcfyk
2015-08-17 16:17:08 +08:00
@haiyang416 我晕。。对 LZ 这种新手来说,这个明显比 session 难多了好吧。。

对新手来说, session 可以简单认为就是安全的, cookie 是不安全的。存取 session 只需要非常简单一行代码就搞定。这还不够简单还要取 uid ,加盐, hash 。。。 LZ 会晕的。
abcfyk
2015-08-17 16:29:35 +08:00
我的一些见解。希望能帮到你。

Q :出于安全考虑,各位在开发的时候,在本地 Cookie 会放一些什么内容?
A : cookie 通常用于保存非敏感信息。比如 userId ,记住密码的开关,比如 authCode 也是这种

Q :本地的 Cookie 内容是怎么和服务器上的 Session 打交道?
A :注意看 phpsessid 那个东西,这个可以认为是服务器上随机生成的一个随机数,对用户 /浏览器 /浏览进程唯一,每次浏览器请求服务器的时候会说:“哎,你给我 xx 页面的东西。我的 sessionId 是 xx ”。然后服务器上跑的 PHP 可以通过 nginx/apache 拿到这个 sessionId ,也就知道你是谁了。你的身份就对应上了。

Q :然后,有没有必要在 user 表中增加一个字段比如说叫做 AuthCode ,再浏览器 POST 过来的 username 和 password 去数据库对比成功之后,将这个 AuthCode 写到 Cookie 去,下次浏览器发送请求的时候直接对比 username 和 AuthCode 就行了?
A :没有必要

Q :其次,我看了 WordPress 和 Typecho 的数据库表结构,里面没有类似于 AuthCode 的字段,但是登录之后却会有这么一个类似于 AuthCode 的 Cookie 值。
A :我一般会用 AuthCode 做记住密码的开关或者权限等级等一些信息。其他 PHPer 我不清楚。。

Q :网上那些教程都只简单的说了下到本地设置个 Cookie 就行了,这样真的安全?
A :不是很明白这个说法。本地设置 cookie 是设置什么?名称是什么?值是什么? Web 开发一个原则就是永远不要相信用户的输入,所有保存在客户端的信息都是非常不安全的。

Q :处理登录的时候,各位是怎么在程序中实现的?能否说一下大致思路?
A : 额。。太长了。有空再写。


A :
haiyang416
2015-08-17 17:11:36 +08:00
@abcfyk session 保存登录状态,浏览器关闭就没了,每次打开浏览器都重新登录?设置 cookie 的保存时间会比设置 session 的生命周期更难? 什么都保存在 session 里,只靠 session id 裸奔,真的会比 cookie 安全?
jugelizi
2015-08-17 21:42:22 +08:00
@abcfyk 不要误导人
session 是依赖 cookie 的 cookie 做的不好 session 没有任何安全可言
网上加密方法很多, userid 和 IP 以及特定的 key 生成 cookie 服务端可以解开基本就认为安全的
incompatible
2015-08-18 01:27:41 +08:00
@haiyang416
@jugelizi

cookie 与 session 跟 安全 是八竿子打不着的关系
简单来说 cookie 是保存在浏览器中的客户信息 session 是保存在服务器端的客户信息

cookie 与 session 唯一的联系就是 一些 Web 应用容器是通过在 cookie 中设置 sessionId 的方式来实现客户与 session 的绑定的(在浏览器不支持 cookie 的情况,比如 Java 的 servlet 容器会通过重写 url 、在所有 url 后加上 jsessionid 的方式来实现客户与 session 的绑定)

至于‘登录后记住我’这种功能,其实就是一个鉴权的过程。首次登录时浏览器中的网页发送用户名和密码给服务器端,服务器完成鉴权后,发给客户一个凭证,此后的客户的访问,带着凭证来证明合法身份即可。
这个凭证理论上来说你可以选择放在 cookie 中,也可以选择放在 session 中,两种方式的安全性是一致的。但实际上如果放在 cookie 中,服务器端依然要护凭证和 cookie 的对应关系及过期时间,还不如干脆放在 session 中来得省事儿。


以上过程中有两个安全弱点。 一是鉴权过程中用户名和密码会被截获(使用 https 可破)。 二是完成鉴权后的访问中, cookie 被截获(使用 https 可破)或者被冒用(请不要把钥匙交给别人)。 显然这都不是 cookie 或 session 可以解决的问题。所以说‘ cookie 跟 session ’与‘安全‘没有关系。


至于把 userId+IP+特定 key 加密再到服务器端解,这是非常不靠谱的。我若是破解了你的加密算法,岂不是我可以想登录哪个用户就登录哪个用户?
haiyang416
2015-08-18 04:33:41 +08:00
@incompatible 请只用 session 实现「记住我」一个月的功能,并且比用 cookie 更适合新人博客练手。
另外,算法不是你想破解就破解,比如 uid 为 1 的 hash 为 dc0afe3bee4310343511b13f2cd8ac19c8ddfaf9572c13e02c44bddf8722b722 ,算法为 sha256 (uid + salt ),请“破解” uid 为 2 用户的 hash 。
haiyang416
2015-08-18 05:04:48 +08:00
对此帖的回复到此为止。
楼主可以鉴别和选择对自己有用的信息,能解惑最好。
haiyang416
2015-08-18 05:54:29 +08:00
忘记贴一个网址了: https://paragonie.com/blog/2015/04/secure-authentication-php-with-long-term-persistence#title.2
内容包含登录相关所有基本操作,建议一读。
jugelizi
2015-08-18 08:44:43 +08:00
想了下还是回复下 在 php 的 session 中默认使用的文件管理,而且过期删除机制的随机性,我不认为在大中型项目中使用 session 来做用户凭证,要么 cookie 走加密,参见 discuz ,或者用 redis 等实现 session 存储,默认文件读写的导致的锁是会有问题的。
incompatible
2015-08-18 10:53:42 +08:00
@haiyang416 为什么要” 请只用 session 实现「记住我」一个月的功能“?就因为你贴那个英文文章里建议这么做(并且没有解释原因)?

关于算法破解,你赢了,我个人破解不了 uid 为 2 的 hash😂
但是破解这个难道不是时间问题?
haiyang416
2015-08-18 11:08:12 +08:00
@incompatible 最后回复一次,我给你一个理由,请试想这样一个情形:
楼主写好了自己的博客系统,登录状态保存在 session 里,楼主听着歌儿,打开博客编辑器,愉快的写着文章。
一篇很好的文章花了楼主 45 分钟时间,完成后点击了发布按钮,然后,就没有然后了。
由于楼主写文章过于专注, 45 分钟内没有刷新或者访问自己的博客,等到点击了发布按钮后才发现自己被跳转到了登录界面,由于楼主没有事先保存文章,所以写好的文章就这么丢失了,楼主怒了,我明明登录了,为什么为什么为什么现在又要我登录?
devion
2015-08-18 11:22:52 +08:00
原来是这样的!
incompatible
2015-08-18 13:11:14 +08:00
@haiyang416 难道“只用 session 实现「记住我」一个月的功能”就能杜绝这个问题了?😢

另外,为什么 45 分钟楼主没有刷新 /访问自己的博客 session 就没了? 以及 #24 “ session 保存登录状态,浏览器关闭就没了,每次打开浏览器都重新登录”这又是为什么? 你确定你足够懂 session 的运行机制?
haiyang416
2015-08-18 13:20:03 +08:00
@incompatible 你真的会 PHP ?
elvba
2015-08-18 23:04:55 +08:00
@haiyang416 很明显他是会的,我也想知道为什么 45 分钟没有刷新 /访问自己的博客 session 就没了,这个 45 分钟时怎么来的?另外 “ session 保存登录状态,浏览器关闭就没了”,你自己登录 V2EX 关闭浏览器后就要重新登录了么?
haiyang416
2015-08-19 08:29:36 +08:00
@elvba 这个帖子里讨论的是新手练习写博客系统,所以我在第一次回复中就说了, session 的运行机制要比 cookie 复杂,不建议新手深究。至于 45 分钟,是随口说的,在 PHP 中原生 session 生命周期只有大约 24 分钟,并不是只设置携带 session id 的 cookie 的过期时间可以解决的,在服务器中同样可能被 GC 。所以就避免不了要设置服务器 session 的生命周期,就会牵扯到 php. ini 中 session 相关的设置,比如生命周期,最大生命周期,回收概率计算,保存位置等等。并且这个设置是全局性的,所以会影响到整个博客系统甚至同服务器其他 PHP 程序。当然这些设置可以在 PHP 脚本中设置,但是需要保证每次启用 session 时都必须设置,不然仍然可能被 GC 。当然,有些人会先将楼主设定到 PHP 程序员的水平,认为这些设置都是非常简单的,或者可以放弃原生 session 使用其他储存方式,并且部署 SSL 来保证 session id 不被截取。
反倒是前面回复中提到的每次打开网页都查询数据库和使用 cookie 的方式被人不耻,其实楼主提到的 typecho 就是这么做的, WordPress 中是又怎么做的 ?前面某位,他的作品有几万人玩,我也玩了一年多了,但是也被说成外行,没办法。
gdtv
2015-10-20 20:24:25 +08:00
@haiyang416
@incompatible

抱歉我挖坟了,因为我最近在做用户登录模块。
在 PHP 里,只用 session 应该是实现不了“记住密码”功能的,@haiyang416 说得没错,如果要实现这个功能只能借助 cookie ,那又涉及 cookie 的加密了,那就回到了 @haiyang416 的观点“要同时处理 session 和 cookie ”,那我何不一开始就只处理 cookie 呢?
我比较赞同 @haiyang416

还是希望 @incompatible 能说一下只用 session 实现记住密码的功能,如果能实现,那比用 cookie 简单方便多了。

PS: phpmyadmin 登录后 24 分钟不操作就会被自动注销登录,就是因为 session 有生存期,并不是只有关闭浏览器才失效。
incompatible
2015-10-21 03:49:40 +08:00
@gdtv 抱歉此中我的回帖在 36 楼就终结了 因为我真的不会 php😂 所有关于 cookie 和 session 的机制我都是从 http 权威指南以及 java servlet 规范中习得的

如果 php 真的有 24 分钟后 session 就被 gc 这样的诡异机制,那它绝对妄称 V2EX 上“最好的编程语言”

但是请相信我,没有比使用 session 实现“登录后记住我”更正统的方式。你需要的就是在服务器端维持这个 session 足够长的有效性,以及在浏览器端维护一个与该 session 对应的 cookie 。

在数十万并发的 java web 系统的中,我通过把 session 放在 redis 中的方式来实现应用服务器的 scale out 以及 session 的有效性。在 php 中,请按照 37 楼的提示对 php 进行配置。总之一个只有 24 分钟生命的 session 绝对是不正常的。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/213573

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX