以登陆注册理解Cookie的做用过程

这篇文章是前一篇文章(Cookie理论知识)的实践性理解javascript

完整代码:html

完整代码前端

Cookie在注册登陆时的做用过程:

注册

注册时把帐号密码写入数据库java

登陆

第一次登陆时服务器给浏览器发送Cookie.node

后台的登陆路由代码(nodejs):git

else if (path === '/sign_in' && method === 'POST') {
        readBody(request).then((body) => {
            let strings = body.split('&') // ['email=1', 'password=2', 'password_confirmation=3']
            let hash = {}
            strings.forEach((string) => {
                // string == 'email=1'
                let parts = string.split('=') // ['email', '1']
                let key = parts[0]
                let value = parts[1]
                hash[key] = decodeURIComponent(value) // hash['email'] = '1'
            })
            let {
                email,
                password
            } = hash
            var users = fs.readFileSync('./db/users', 'utf8')
            try {
                users = JSON.parse(users) // []
            } catch (exception) {
                users = []
            }
            let found
            for (let i = 0; i < users.length; i++) {
                if (users[i].email === email && users[i].password === password) {
                    found = true
                    break
                }
            }
            if (found) {//关键在这里,验证成功,设置登陆Cookie为登陆的邮箱,并放在响应里发给浏览器
                response.setHeader('Set-Cookie', `sign_in_email=${email}`)
                response.statusCode = 200
            } else {
                response.statusCode = 401
            }
            response.end()
        })
    }

在登陆成功的一瞬间,须要后台设置一个Cookie,记录一下登录的用户id(这里用邮箱表示,代码在上面),而后发响应给浏览器
例如在服务器端设置响应头:set-cookies:user_email=1@mtt.comgithub

这时候咱们查看响应:数据库

clipboard.png

发现响应头已经设置cookie.segmentfault

clipboard.png

而后跳转到主页,这时候咱们查看跳转到主页的请求:后端

clipboard.png

发现跳转到主页的请求头中包含cookie字段(之后访问这个域名都会带着这个Cookie)!因此,就像上篇文章说的:

若是服务器给了浏览器一个setcookie的响应头,那么这个浏览器之后全部的请求,只要是相同的源(即就是上次给我发送Cookie的那个域名,域名和端口相同),那就么就会把当时服务器发给这个浏览器的Cookie带着

之后,浏览器一旦访问这个路径,浏览器就会附上这段 Cookie 发送给服务器

即:第一次请求,服务器为浏览器设置Cookie.下次请求,浏览器带上Cookie,发送给服务器.
第一次登陆的时候,服务器给浏览器的响应设置一个Cookie,set-cookies:user_email=1@mtt.com,而后当浏览器下次进行请求的时候,发现Cookie中有名为User_email的Cookie,并且我发送请求的域名仍是上次发给我带Cookie的响应的那个域名.

那么就无需再次登陆了.至关于服务器给浏览器发了进入门票,下次或下下次浏览器在进入服务器的时候给服务器看票就能够了

后台读取Cookie保留登陆状态与删除Cookie退出登陆状态

首页代码:

<body>
    <h1>我是首页</h1>
    <div class="">
        <a href="./sign_up">注册</a>
        <a href="./sign_in">登陆</a>
    </div>
    
    <h1>你的状态是:__status__</h1>
    <h1>你的邮箱帐号是:__email__</h1>
    <h1>你的密码是:__password__</h1>

    <a href="javascript:;" id="logOffBtn">退出登陆(删除cookie)</a>

</body>
<script>
logOffBtn.addEventListener("click", () => {
        // 删除一个现存 Cookie 的惟一方法,是设置它的expires属性为一个过去的日期。
        document.cookie = 'sign_in_email=;expires=Thu, 01-Jan-1970 00:00:01 GMT'
        window.location = "/"
    })
</script>

后台路由代码

if (path === '/') {
        response.statusCode = 200
        let string = fs.readFileSync('./index.html')
        string = string.toString();
        var users = fs.readFileSync('./db/users', 'utf8')
        users = JSON.parse(users)//转化为user对象数组

        console.log(users);
        let cookies = request.headers.cookie || ''//['email=111', 'asdasd=111']
        cookies = cookies.split("; ")
        let hash={}
        cookies.forEach((string)=>{
            let parts = string.split("=")
            let key = parts[0]
            let value = parts[1]
            hash[key] = value;
        })
        
        let eamil = hash.sign_in_email
        let foundedUser
        users.forEach((userObj)=>{
            if(userObj.email===eamil){
                foundedUser = userObj;
            }
        })
        console.log(foundedUser);
        if(foundedUser){
            string = string.replace('__status__', '已登陆')
            string = string.replace('__email__', foundedUser.email)
            string = string.replace('__password__', foundedUser.password)
        }else{
            string = string.replace('__status__', '未登陆,请去登陆')
            string = string.replace('__email__', '没')
            string = string.replace('__password__', '没')
        }
        
        response.setHeader('Content-Type', 'text/html;charset=utf-8')
        response.write(string)
        response.end()
    }

在没有Cookie的时候,首页的状态

clipboard.png

登陆以后,后台根据Cookie查询数据库,将用户名与密码传到前台的首页上

clipboard.png

退出登陆将删除Cookie并刷新页面,从新回到未登陆的状态

Cookie在登陆的时候的特色

咱们获得Cookie的特色:

  1. 第一次登陆的时候,服务器经过 Set-Cookie 响应头设置 Cookie,而后以响应的形式发给浏览器
  2. 浏览器获得 响应中Cookie 以后,以后每次请求这个域名都要带上这个 Cookie
  3. 以后服务器读取当时本身设置的 Cookie 就知道登陆用户的信息(email)

几个关于Cookie的问题

1.我在 Chrome 登陆了获得 Cookie,用 Safari 访问,Safari 会带上 Cookie 吗
no

2.Cookie 存在哪
Windows 存在 C 盘的一个文件里

3.Cookie会被用户篡改吗?
能够,例如在谷歌浏览器开发者模式下的application->Cookie中能够手动修改,修改以后,下次发送请求时,附带的就是修改后的Cookie

修改Cookie

JS中也有能够操做cookie的api
( 假如换成别的用户的帐号,那么还能够登陆成功的话,就会存在风险问题.Session 来解决这个问题,防止用户篡改)
后端能够强制设置不容许修改Cookie,只要将Cookie的属性设置为Httponly便可(还能够手动改,可是JS改不了,也没法获取),具体语法看 MDN
4.Cookie 有效期吗?
默认有效期20分钟左右,不一样浏览器策略不一样(若是浏览器一直开着,那么Cookie不会被删除.若是关闭浏览器,那么浏览器为了安全考虑,20分钟左右后可能会删除Cookie.这也取决于服务器如何设置Cookie的有效期)
后端能够强制设置有效期,具体语法看 MDN
Cookie 遵照同源策略吗?
也有,不过跟 AJAX 的同源策略稍微有些不一样。
当请求 qq.com 下的资源时,浏览器会默认带上 qq.com 对应的 Cookie,不会带上 baidu.com 对应的 Cookie
当请求 v.qq.com 下的资源时,浏览器不只会带上 v.qq.com 的Cookie,还会带上 qq.com 的 Cookie
另外 Cookie 还能够根据路径作限制,请自行了解,这个功能用得比较少。

须要注意的细节问题

为何先后端都要进行表单验证?

先后端都要验证邮箱格式是否正确,帐号密码格式是否正确,两次提交的密码是否相同等。
由于黑客能够绕过前端的js验证流程,例如黑客能够直接使用curl 进行请求的发送,直接与后台服务器进行交互。
如图:

clipboard.png

因此后台也须要进行表单验证。

Cookie如何手动关闭

clipboard.png

翻译

cookie:曲奇饼cache-control:缓存控制

相关文章
相关标签/搜索