请问一下大家平常都是怎么验证用户登录的? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
feikeq
V2EX    PHP

请问一下大家平常都是怎么验证用户登录的?

  •  
  •   feikeq 2013-02-26 17:11:42 +08:00 8393 次点击
    这是一个创建于 4658 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一般情况下网站都会记录用户登录成功的cookie记录,但我为了安全,用户的每一次操作我都会去和数据库验证一次,就是无论用户打开页面还是添加一条操作都会验证。这很明显加重了MYSQL查询的负担,有没有更简单有效一点的方法?
    14 条回复    1970-01-01 08:00:00 +08:00
    jybox
        2
    jybox  
       2013-02-26 17:20:05 +08:00
    我之前是这样的,数据库里面是 hash(hash(user)+hash(passwd)) 记作dbPasswd
    然后在配置文件里面写了个全局的干扰码记作cookieCode

    用户登陆后写到cookie里面的大概就是 hash(dbPasswd+cookieCode)
    然后每次刷新页面都会连接数据库验证一次,和楼主的差不多,好处就是代码很简单....写到一个类里面不过四五十行.


    正在编写中的新版网站是这样的,每次登录成功后随机生成一个字符串写入Cookie, 记作token, 存入数据库. 然后同时把当前的登录状态记入session.
    验证时如果session中已有登录状态就用session的, 没有的话再检查Cookie里的token是否在数据库中.

    这样的好处就是减少了查询数据库的次数,同时可以单独追踪和取消每个会话的授权(删掉对应的token就行).
    jybox
        3
    jybox  
       2013-02-26 17:20:53 +08:00
    我没看过太多这方面的资料...都是自己摸索出来的..可能不太成熟.
    feikeq
        4
    feikeq  
    OP
       2013-02-26 17:28:31 +08:00
    @jybox session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能....
    fork3rt
        5
    fork3rt  
       2013-02-26 17:29:29 +08:00
    SESSION
    feikeq
        6
    feikeq  
    OP
       2013-02-26 17:29:32 +08:00
    @binux 翻译过来还是云里雾里的.....
    ---------------------------------------
    会话管理

    在人机交互,会话管理的过程中,保持互动的整个会话跟踪用户的活动的计算机系统。
    在一个桌面环境中的典型会话管理任务,包括记录哪些应用程序是开放的,它记录了每个应用程序已打开,让相同的状态,当用户登录,登录后,可以恢复。对于一个网站,会话管理可能会要求用户重新登录会话已过期(即在一定期限后没有用户活动)。它也可用于将信息存储在服务器端的HTTP请求之间。
    [ 编辑 ] 桌面会话管理
    一种桌面会话管理器是一个程序,可以保存和恢复桌面会话。桌面会话是当前正在运行的所有窗口和当前的内容。基于Linux的系统上所提供的X会话管理器会话管理。在微软Windows系统中,没有会话管理器是包含在系统中,但可以提供的第三方应用程序,如twinsplay会话管理。
    [ 编辑 ] 浏览器会话管理
    会话管理是在一个Web浏览器,用户可以在其中保存所有打开的页面和设置,并恢复他们在以后的日子特别有用。为了帮助恢复系统或应用程序崩溃,也可以被还原页面和设置下运行。谷歌Chrome,OmniWeb和歌剧的Web浏览器,支持会话管理的例子。其他现代的浏览器,如Mozilla Firefox浏览器支持会话管理,通过第三方插件或扩展。会话管理往往是通过cookie的应用管理。
    [ 编辑 ] Web服务器会话管理
    超文本传输协议(HTTP)是无状态的:一个客户端计算机上运行Web浏览器与每一个新的HTTP GET或POST请求,必须建立一个新的传输控制协议(TCP)网络连接到Web服务器。该网站的服务器,因此,不能依靠已建立的TCP网络连接的时间不是一个单一的HTTP GET或POST操作。会话管理是由Web开发人员所使用的技术,使无状态的HTTP协议支持的会话状态。例如,当一个用户到Web服务器的身份验证,用户的HTTP请求(GET或POST)不应该导致Web服务器要求用户的帐号和密码。所采用的方法来完成此看到的HTTP cookie和会话ID的讨论。
    [世界上第一个会话管理系统被称为神,发明和开发的大卫Hostettler韦恩于1996年。使用Web浏览器的文字和图像应用程序被视为最好安装定制的MS-Windows的客户端或X Window的服务器,特别适用于低带宽连接。但是最初并不支持HTTP/1.0的Web 会话的所有功能。然而DHW创造一种变通方法使用会话ID,NCSA httpd的版本1.0的马赛克和Netscape的工作。整点的会话ID是整个会话状态并不需要被递到/从客户端/服务器通过HTTP Cookie的每个交易阶段。]
    的会话信息存储在web服务器上,使用产生的作为结果的第一个(有时第一个认证。)运行Web浏览器从最终用户请求的会话标识符的会话ID。会话ID和相关联的会话的数据(用户名,账户号码等)在Web服务器上的“存储”,是通过使用各种技术,包括,但不限于,本地存储器,平面文件和数据库。
    在多个Web服务器的情况下,必须分享知识的会话状态(这是典型的在一个集群环境中)的会话信息必须正在运行Web服务器软件的群集节点之间共享。在群集的节点之间共享会话状态的方法包括:成员节点多播会话信息(见JGroups的这种技术的一个例子),与合作伙伴节点使用分布式共享内存或内存虚拟化共享的会话信息,在节点之间使用共享的会话信息网络插座,会话信息存储在一个共享的文件系统,如网络文件系统或全局文件系统,或群集之外的在数据库中存储会话信息。
    如果会话信息被认为是短暂的,不稳定的数据,并不需要交易的不可抵赖性和不包含数据(例如在美国,健康保险可携性及责任性法案,萨班斯-奥克斯利法案“合规性审计法两部法律必须遵守审计)的例子,然后可以使用任何存储会话信息的方法。但是,如果会话信息是合规性审计,应考虑给定的会话存储,复制和集群所采用的方法。
    在构建一个面向服务的架构,简单对象访问协议或SOAP消息的可扩展标记语言(XML)消息可用于消费类应用,导致Web服务器创建会话。
    binux
        7
    binux  
       2013-02-26 17:31:38 +08:00
    @feikeq 就是通过加密cookie,直接在cookie中保存,而客户端亦无法伪造
    gamexg
        8
    gamexg  
       2013-02-26 21:20:52 +08:00
    大部分系统都是 cookie 里面存放session id,然后用户相关信息放到 session 里,session 存放到 Memcached 之类的缓存上面。
    weicode
        9
    weicode  
       2013-02-26 22:13:28 +08:00
    将用户UID加密后后存入COOKIE,也就是所谓的token值。根据token解密后的UID获取用户信息,进而判断是否登录。现在有加密解密支持过期时间,比如DISCUZ加密解密函数。定期更换密钥KEY。
    这样做的弊端若用户修改密码此token还是有效的。避免XSS漏洞,可将此COOKIE设置成HTTPONLY COOKIE。
    xing393939
        10
    xing393939  
       2013-02-27 10:33:05 +08:00
    @weicode "避免XSS漏洞,可将此COOKIE设置成HTTPONLY COOKIE。" HTTPONLY COOKIE 能防止伪造么?
    raincious
        11
    raincious  
       2013-02-27 15:09:39 +08:00
    @jybox 我的方法也跟你类似,不过我还是用了每次打开页面都得找一次数据库的作法。因为我参考Discuz 6那时代的代码来构建我的Session管理器时,发现Discuz即使这样做了,速度也很快。

    但还是看负载需求吧,如果网站太大了,估计就得用Ajax配合等页面打开后读取Session然后改页面这样了估计。

    我的方法是:
    1、用户打开网页时,先检测Cookie,如果有我之前设定的Cookie,则使用那个Cookie在数据库中一个特殊的表里搜索用户等入记录,如果没有这个记录,则将用户会话标记为Guest(不给他分配用户ID)。

    2、如果找到了这个记录,通过等入记录、用户记录进行比对,如果有这个用户、而且登入可用,则将会话标记为Member(给他分配一个用户ID)

    应用程序里使用 if (MemberID) 来检测用户是否登陆过。

    如果在第一步里,用户没有发送任何Cookie,则非随机产生一个,比如可以通过IP地址什么的,然后发送这个给用户,同时启用PHP自己的Session,记录这个Cookie。

    可能说得不是很清楚,这里有源代码(Discuz 6时代构建的,一直没怎么改而且为了兼容性,写得很长),可以参考下:https://code.google.com/p/faculaframework/source/browse/trunk/include/class.session.php

    这里有使用的例子:http://test.refugeone.com/ // 除了登陆和用户管理外完全不能工作的网站
    feikeq
        12
    feikeq  
    OP
       2013-03-01 16:57:03 +08:00
    @raincious 为了 www。tibiji。com 服务器性能我最终放弃 session 这种方法,还是用cookie。
    作法是:
    1.先生成一个加密的token保存用户登录状态cookie 时间为一月或半年
    2.再生成一个根据IP地址加密码的cookie、限制时间为1天或2天

    验证方法是
    一、如果有cookie记录2号并且当前用户的IP地址相符则直接登录成功不用去数据库里验证。
    二、如果2号cookie记录与用户IP不匹配就用1号cookie去数据库里验证
    三、如果1号cookie验证通过则更新2号cookie,反之则重新让用户手动登录。


    这样就能适当给Mysql缓解查询压力了....
    jybox
        13
    jybox  
       2013-03-02 23:17:39 +08:00
    soli
        14
    soli  
       2013-04-23 10:51:05 +08:00
    没人考虑 CSRF 么?
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2651 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 12:53 PVG 20:53 LAX 04:53 JFK 07:53
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86