session与cookie

本文详细解析网络请求中的Cookie与Set-Cookie交互模式,阐述SessionID在用户身份识别中的作用,探讨Cookie缓存、Session生命周期及安全性考量,同时介绍跨域请求中Cookie与Session机制的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

网络请求中的cookie与set-Cookie的交互模式和作用

1.当很多人访问统一个网服务器,服务器如何来区分不同的用户呢?

答:sessionid,sessionid保证了浏览器和服务器唯一性的通信凭证号码,session保存在服务器上,
sessionid保存在浏览器等客户端,服务器根据浏览器发送来的sessionid作为一个唯一的key值找到
对应的用户,所以说sessionid的唯一性用来区别和查询用户信息,因此sessionid的作用不言而喻了吧。

2.我们经常说浏览器关闭后session就会被清除,那session有生命周期么?

答:有的,这个是服务器的配置,浏览器关闭只是把sessionid给清除了,所以在此打开浏览器并请求服务,
你的登录状态无法找到,由此你需要重新登录。
一般情况下,浏览器如果不刷新或者不重新请求的话,服务器一般会缓存session数据20分钟左右。

3.cookie会被缓存,sessionid保存在cookie中,sessionid一定会被清除么?

答:不一定,这个需要服务器cookie的设置了,但总体而言,因安全性考量,最好不要缓存sessionid

4.cookie保存用户状态时需要保存sessionid么?

答:不需要,保存user_id或者其他token即可

5.cookie是如何发送到服务器的?

答:使用http请求头,浏览器进行了封装,但在一般网络编程时可以加上

GET / HTTP/1.1
Host: www.guancha.cn
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.124 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: pgv_pvi=9956446208; pbm_total_match_cookie_281589=1; has_js=1; Hm_lvt_8ab18ec6e3ee89210917ef2c8572b30e=1414852570,1414879794,1414884316,1414901793; Hm_lpvt_8ab18ec6e3ee89210917ef2c8572b30e=1414901793

6.上面的例子中没有sessionid么?

答:是的,没有,sessionid只是一个代称,这个变量名可以改变,比如在php中使用phpsessid,
在java web中jsessionid

7.登录前有sessionid,登陆后需要重新设置么?

答:依情况而定,如果安全性要求较高的,可以重新生成一个sessionid,另外必须先销毁之前的一个sessionid

8.sessionid生成后如何发送到浏览器?

答:默认情况下,服务器会挂载响应消息 set-Cookie来指示浏览器更新sessionid,不需要手动更新

如:

HTTP/1.x 200 OK 
X-Powered-By: PHP/5.2.1 
Set-Cookie: TestCookie=something from somewhere; path=/ 
Expires: Thu, 19 Nov 2007 18:52:00 GMT 
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0 
Pragma: no-cache 
Content-type: text/html 

//如果是按照第7问生成的sessionid,这个也不需要手动发送,当然也可以手动发送

9.单点登录中,cookie被禁用了怎么办?(一点登陆,子网站其他系统不用再登陆)

单点登录的原理是后端生成一个 session ID,设置到 cookie,后面所有请求浏览器都会带上cookie,然后服务端从cookie获取 session ID,查询到用户信息。

所以,保持登录的关键不是cookie,而是通过cookie 保存和传输的 session ID,本质是能获取用户信息的数据。
除了cookie,还常用HTTP请求头来传输。但这个请求头浏览器不会像cookie一样自动携带,需手工处理

前后端分离session机制的使用(只针对浏览器,app不行)

1.解决跨域问题(CORS)

前后端部署在不同的服务器以及端口,两者不同源,首先要让服务器可以跨域被访问:Access-Control-Allow-Origin: *

2.ajax实现不同源cookie的携带

  • ajax会自动带上同源的cookie,不会带上不同源的cookie
  • 可以通过前端设置withCredentialstrue, 后端设置Header的方式来让ajax自动带上不同源的cookie,但是这个属性对同源请求没有任何影响, 会被自动忽略。
<script>
    $.ajax({
        url: "http://localhost:9000",
        type: 'GET',
        xhrFields: {
            withCredentials: true // 这里设置了withCredentials
        },
        success: function(data) {
            console.log(data)
        },
        error: function(err) {
            console.error(err)
        }
    })
</script>
  • ajax请求是有同源策略的,虽然可以应用CORS等手段来实现跨域,但是这并不是说这样就是“同源”了。ajax在请求时就会因为这个同源的问题而决定是否带上cookie.

ajax跨域携带cookie的验证:

第一步: 建立一个本地服务器
  • 新建一个demo文件夹,进入文件夹,用php -S localhost:9000开启一个本地服务器
    在demo文件夹下新建一个index.php文件, 内容为:
<?php
    header("Access-Control-Allow-Origin: http://localhost:9999");
    header('Access-Control-Allow-Credentials:true');
    $value = "something with cookie";
    setcookie("testcookie", $value, time() + 3600);
    echo "cookie has seted";

注意: Access-Control-Allow-Origin必须制定特定的URL,不能是*, 且需要加上Access-Control-Allow-Credentials

第二步: 编写请求测试代码

1.在桌面上新建一个test.html文件,内容为:

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
</head>
<body>
    <script>
        $.ajax({
            url: "http://localhost:9000/",
            type: 'GET',
            success: function(data) {
                console.log(data)
            },
            error: function(err) {
                console.error(err)
            }
        })
    </script>
</body>
</html>
  1. 在desktop目录下起一个服务器,用php -S localhost:9999开启一个本地服务器
第三步: 测试
  1. 在浏览器中访问localhost:9999/test.html,打开调试工具->application->cookie可以看到cookie设置成功。
  2. 打开调试工具->netwoek,刷新一下,可以看到一个localhost请求,检查这个localhost请求的Request Headers,发现没有cookie这个头部,说明不同源的请求时不会带上cookie的(即使有CORS)
  3. 把test.html放到demo文件夹下,在访问localhost:9000/test.html,查看Request Headers,会发现cookie头部, 说明同源请求自动带上了cookie
  4. 把test.html的内容更改为以下内容,请求时会有cookie头部。说明withCredentials起作用了
<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="jquery-2.2.4.min.js"></script>
</head>
<body>
    <script>
        $.ajax({
            url: "http://localhost:9000",
            type: 'GET',
            xhrFields: {
                withCredentials: true // 这里设置了withCredentials
            },
            success: function(data) {
                console.log(data)
            },
            error: function(err) {
                console.error(err)
            }
        })
    </script>
</body>
</html>

3.跨域前后端分离,session机制的实现

根据浏览器的保护规则,跨域的时候我们创建的sessionId是不会被浏览器保存下来的,这样,当我们在进行跨域访问的时候,我们的sessionId就不会被保存下来,也就是说,每一次的请求,服务器就会以为是一个新的人,而不是同一个人,为了解决这样的办法,session每次都会被刷新,解决:

a.允许服务器向浏览器跨域响应时更改浏览器(客户端)的cookie

服务器端:res.setHeader("Access-Control-Allow-Credentials", "true");

b.ajax请求携带cookie
$.ajax({
    url:url,
    //加上这句话,允许浏览器向服务器跨域请求时携带cookie
    xhrFields: {
               withCredentials: true
           },
           crossDomain: true,
     
    success:function(result){
        alert("test");
    },
    error:function(){
    }
});
c.注意 Credential is not supported if the CORS header ‘Access-Control-Allow-Origin’ is ‘*’
  • Access-Control-Allow-Origin: "*"Access-Control-Allow-Credentials: true是相互矛盾的,设置允许访问的源为*时,便不能使用credential
  • 可以指定固定域:Access-Control-Allow-Origin: "http://10.10.0.100"
  • 也可在程序内,实时获取请求的地址setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));//设置允许跨域请求地址即为当前请求地址
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值