使用cookie做用户登录的过程详解

不管是游戏,还是网站,最基本的功能,就是用户注册登录。

或许,我们做过多次用户的登陆注册的功能,但我们是否想过,为什么要实现用户的登录。用户怎样做才算登录成功。

对用户而言,登录后,就有了他的一片“天地”,例如,登录CSDN后,就可以管理自己的博客,否则,你没有权利管理。关于是否登录成功的问题,在用户看来,如果用户名和密码输入成功,就算登入成功,否则,登录不成功。

但这一切,在程序中是怎样实现的呢?在程序中,怎样判定这个用户处于登录状态,怎样判断用户是否有权利访问某个URL,例如管理自己的博客。

为了搞清楚上面的问题,需要我们了解的一个知识点是,HTTP协议实际上是无状态的,非持久连接。也就是说,你第二次通过某个浏览器访问WEB应用,他其实不知道你已经来过一次了。

这里,有一个问题就是,我们的需求是需要知道用户“是否登录”了,即当这个用户登录后,第二次访问的服务器的时候,服务器需要知道请求是来自同一个用户,可是,由于HTTP协议是无状态的,服务器无法知道两次访问是不是来自同一个人。

这里就使用到COOKIE技术了,使用COOKIE可以解决以上问题,让服务器知道用户是否登录。

cookie是什么?
cookie是一个文本文件,保存在客户端硬盘中(如果设置了cookie的过期时间),或者在用户的浏览器内存中(如果cookie是临时的)。这个文件对用户来说,是透明的,你可以通过浏览器工具来查看当前的cookie,可能不止一个。

cookie是什么时候被保存在浏览器中的?

这个问题很重要,浏览器的cookie值不会凭空产生。它是服务器端给客户端的。如果用户浏览器支持COOKIE,使用下面一段代码就可以创建COOKIE。

setcookie($name, $value, $expire, $path, $domain, $secure)

$path: 表示cookie在服务器端的指定路径,如果不设置,则路径为目录,服务器中的所有脚本都可以访问到

$domain: 表示这个cookie所属的域,cookie是不能跨域访问的。

例如:

setcookie('xxx', 'yyyyyyyyyyyyy');

当 用户第一次访问这段程序的时候,setcookie函数会生成cookie文件,并保存在浏览器的response Header,注意,这个时候,如果访问服务器中的全局数据$_COOKIE,会发现这个数组为空。此时,客户端还没有把cookie信息传到服务器端。

浏览器还没有保存这个cookie



当第二次访问这个页面的时候,这个时候,浏览器会自动把cookie信息传到服务器端(如果这个cookie没有过期的话)。这样,服务器才保存了这个cookie。



服务器中,如果获取到这个cookie值?

在PHP中,任何从客户端传过来的cookie都可以保存在$_COOKIE这样的全局函数中。在服务器端,可以通过这个数组来访问cookie的信息。记住,第一次读取它的信息的时候,并不会生效。原因就是我上面说的。


那么我们怎么利用cookie实现用户登陆呢?

流程图:



使用COOKIE保存用户的TOKEN值。这样,服务器会读取保存在$_COOKIE数组里面的信息判断用户是否登陆。


代码展示:

登陆时,当用户输入正确的用户名和密码后,需要调用下面的代码:

    /**
     * 刷新 userToken
     *
     * @param int $uid
     * @param string $userToken
     * @param int $expires
     * @throws Core_Exception_Logic
     * @return void
     */
    private function _refreshUserToken($uid, $userToken = null, $expires = null)
    {
        // 生成新的TOKEN值
        if (! $userToken) {
            $userToken = self::genUserToken($uid);
        }

        // 更新玩家的TOKEN
        if (! Dao('Share_UserIndex')->updateUserToken($uid, $userToken)) {
            throws(_('登陆失败,请稍候再试'));
        }

        // 设置用户凭证到 cookie
        $this->_setUserCookie($userToken, $expires);
    }

为什么登陆成功后,都要更新用户的TOKEN值呢?

防止,如果用户A的token值一直都更新,被用户B窃取,这样,用户B伪造COOKIE,如使用浏览器直接添加一个COOKIE,这样可以直接登陆用户A的账号,绕过了用户名和密码的验证。

第二,就是保证一个账号只能是一个用户登陆。

在控制器的入口处检查用户是否登陆:

abstract class Controller_Abstract extends Core_Controller_Web
{
    /**
     * 构造函数
     */
    public function init()
    {
        // 获取当前已登录用户 userIndex
        if (! $this->_userIndex = $this->_auth->getUserByToken()) {
            $this->_checkAuth && $this->vRedirect('/auth/login');
        }

        // 如果已登录
        if ($this->_userIndex) {

            // 实例化一个玩家实例
            $this->_user = new Model_User($this->_uid);
        }

    }
}


其中 getUserByToken()函数就是根据保存在COOKIE里面的token值来查找用户,如果查找到,说明这个用户已经登陆,否则未登陆。

    /**
     * 获取当前已登录用户信息
     *
     * @return false/array
     */
    public function getUserByToken()
    {
        // 获取用户的标识符
        if (! $userToken = F('Cookie')->get(self::$cookieName)) {
            return false;
        }

        // 根据相应的userToken 查找用户
        return Dao('Share_UserIndex')->getUserByToken($userToken);
    }


注意一点:在登陆的时候,除了使用cookie保存以外,还可以使用session,但是,为什么我们还少使用session做登陆注册呢,因为session的值是保存在服务器中的,在一些大型的应用中,服务器可能不止一台,所以,无法知道,用户注册的session保存在哪台服务器上。

但是,记住一点就是,session可以保存在memcached中。这里需要修改PHP.INI配置文件。

  • 13
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot是一个用于构建Java应用程序的开发框架,它简化了应用程序的开发和部署过程使用Spring Boot可以很方便地实现cookie登录功能。 要实现cookie登录功能,首先需要在Spring Boot应用中添加依赖项,例如spring-boot-starter-web和spring-boot-starter-security。这些依赖项提供了与Web和安全相关的功能。 接下来,需要配置Spring Security来处理身份验证和授权。可以编写一个配置类,并使用@Configuration注解进行标注。在配置类中,可以定义认证管理器、用户服务和密码编码器等相关组件。 在认证管理器中,可以定义验证用户凭据的方式,例如从数据库中验证用户名和密码。也可以自定义用户服务来验证用户凭据。 另外,还需要配置登录页面和登录处理的URL。可以在配置类中使用@EnableWebSecurity注解,然后重写configure方法,指定登录页面URL和登录表单的提交URL。 一旦用户输入了正确的用户名和密码,认证成功后,可以生成一个cookie,并将其添加到HTTP响应中。可以使用Servlet API中的HttpServletResponse对象,调用addCookie方法将cookie添加到响应中。 在后续的请求中,用户的浏览器将自动发送此cookie到服务器。服务器可以使用Spring Security来验证cookie,并判断用户是否已经登录。 使用Spring Boot实现cookie登录功能可以提供良好的用户体验,用户只需要一次输入用户名和密码即可登录成功,并在后续的访问中保持登录状态。同时,Spring Boot提供了丰富的功能和组件,可以很方便地完成这一任务。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值