日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一文彻底搞懂Cookie、Session、Token到底是什么

發布時間:2025/3/16 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一文彻底搞懂Cookie、Session、Token到底是什么 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者:不學無數的程序員

原文鏈接:https://juejin.im/post/5de4c3c76fb9a071b86cc482

Cookie

夏洛:大爺,樓上322住的是馬冬梅家吧?

??大爺:馬都什么?

? 夏洛:馬冬梅。

? 大爺:什么都沒啊?

? 夏洛:馬冬梅啊。

? 大爺:馬什么沒?

? 夏洛:行,大爺你先涼快著吧。

在了解這三個概念之前我們先要了解HTTP是無狀態的Web服務器,什么是無狀態呢?就像上面夏洛特煩惱中經典的一幕對話一樣,一次對話完成后下一次對話完全不知道上一次對話發生了什么。

如果在Web服務器中只是用來管理靜態文件還好說,對方是誰并不重要,把文件從磁盤中讀取出來發出去即可。

但是隨著網絡的不斷發展,比如電商中的購物車只有記住了用戶的身份才能夠執行接下來的一系列動作。所以此時就需要我們無狀態的服務器記住一些事情。

那么Web服務器是如何記住一些事情呢?既然Web服務器記不住東西,那么我們就在外部想辦法記住,相當于服務器給每個客戶端都貼上了一個小紙條。

上面記錄了服務器給我們返回的一些信息。然后服務器看到這張小紙條就知道我們是誰了。

那么Cookie是誰產生的呢?Cookies是由服務器產生的。接下來我們描述一下Cookie產生的過程。

  • 瀏覽器第一次訪問服務端時,服務器此時肯定不知道他的身份,所以創建一個獨特的身份標識數據,格式為key=value,放入到Set-Cookie字段里,隨著響應報文發給瀏覽器。

  • 瀏覽器看到有Set-Cookie字段以后就知道這是服務器給的身份標識,于是就保存起來,下次請求時會自動將此key=value值放入到Cookie字段中發給服務端。

  • 服務端收到請求報文后,發現Cookie字段中有值,就能根據此值識別用戶的身份然后提供個性化的服務。

接下來我們用代碼演示一下服務器是如何生成,我們自己搭建一個后臺服務器,這里我用的是SpringBoot搭建的,并且寫入SpringMVC的代碼如下:

@RequestMapping("/testCookies")public String cookies(HttpServletResponse response){ response.addCookie(new Cookie("testUser","xxxx")); return "cookies";}

項目啟動以后我們輸入路徑http://localhost:8005/testCookies,然后查看發的請求??梢钥吹较旅婺菑垐D使我們首次訪問服務器時發送的請求,可以看到服務器返回的響應中有Set-Cookie字段。而里面的key=value值正是我們服務器中設置的值。

接下來我們再次刷新這個頁面可以看到在請求體中已經設置了Cookie字段,并且將我們的值也帶過去了。這樣服務器就能夠根據Cookie中的值記住我們的信息了。

接下來我們換一個請求呢?是不是Cookie也會帶過去呢?接下來我們輸入路徑http://localhost:8005請求。我們可以看到Cookie字段還是被帶過去了。

那么瀏覽器的Cookie是存放在哪呢?如果是使用的是Chrome瀏覽器的話,那么可以按照下面步驟。

  • 在計算機打開Chrome

  • 在右上角,一次點擊更多圖標->設置

  • 在底部,點擊高級

  • 在隱私設置和安全性下方,點擊網站設置

  • 依次點擊Cookie->查看所有Cookie和網站數據

然后可以根據域名進行搜索所管理的Cookie數據。所以是瀏覽器替你管理了Cookie的數據,如果此時你換成了Firefox等其他的瀏覽器,因為Cookie剛才是存儲在Chrome里面的,所以服務器又蒙圈了,不知道你是誰,就會給Firefox再次貼上小紙條。

Cookie中的參數設置

說到這里,應該知道了Cookie就是服務器委托瀏覽器存儲在客戶端里的一些數據,而這些數據通常都會記錄用戶的關鍵識別信息。

所以Cookie需要用一些其他的手段用來保護,防止外泄或者竊取,這些手段就是Cookie的屬性。

參數名作用后端設置方法

Max-Age

設置cookie的過期時間,單位為秒

cookie.setMaxAge(10)

Domain

指定了Cookie所屬的域名

cookie.setDomain("")

Path

指定了Cookie所屬的路徑

cookie.setPath("");

HttpOnly

告訴瀏覽器此Cookie只能靠瀏覽器Http協議傳輸,禁止其他方式訪問

cookie.setHttpOnly(true)

Secure

告訴瀏覽器此Cookie只能在Https安全協議中傳輸,如果是Http則禁止傳輸

cookie.setSecure(true)

下面我就簡單演示一下這幾個參數的用法及現象。

Path

設置為cookie.setPath("/testCookies"),接下來我們訪問http://localhost:8005/testCookies,我們可以看到在左邊和我們指定的路徑是一樣的,所以Cookie才在請求頭中出現,接下來我們訪問http://localhost:8005,我們發現沒有Cookie字段了,這就是Path控制的路徑。

Domain

設置為cookie.setDomain("localhost"),接下來我們訪問http://localhost:8005/testCookies我們發現下圖中左邊的是有Cookie的字段的,但是我們訪問http://172.16.42.81:8005/testCookies,看下圖的右邊可以看到沒有Cookie的字段了。這就是Domain控制的域名發送Cookie。

接下來的幾個參數就不一一演示了,相信到這里大家應該對Cookie有一些了解了。

Session

- Cookie是存儲在客戶端方,Session是存儲在服務端方,客戶端只存儲SessionId

在上面我們了解了什么是Cookie,既然瀏覽器已經通過Cookie實現了有狀態這一需求,那么為什么又來了一個Session呢?這里我們想象一下,如果將賬戶的一些信息都存入Cookie中的話,一旦信息被攔截,那么我們所有的賬戶信息都會丟失掉。所以就出現了Session,在一次會話中將重要信息保存在Session中,瀏覽器只記錄SessionId一個SessionId對應一次會話請求。

@RequestMapping("/testSession")@ResponseBodypublic String testSession(HttpSession session){ session.setAttribute("testSession","this is my session"); return "testSession";}

@RequestMapping("/testGetSession")@ResponseBodypublic String testGetSession(HttpSession session){ Object testSession = session.getAttribute("testSession"); return String.valueOf(testSession);}

這里我們寫一個新的方法來測試Session是如何產生的,我們在請求參數中加上HttpSession session,然后再瀏覽器中輸入http://localhost:8005/testSession進行訪問可以看到在服務器的返回頭中在Cookie中生成了一個SessionId。然后瀏覽器記住此SessionId下次訪問時可以帶著此Id,然后就能根據此Id找到存儲在服務端的信息了。

此時我們訪問路徑http://localhost:8005/testGetSession,發現得到了我們上面存儲在Session中的信息。那么Session什么時候過期呢?

  • 客戶端:和Cookie過期一致,如果沒設置,默認是關了瀏覽器就沒了,即再打開瀏覽器的時候初次請求頭中是沒有SessionId了。

  • 服務端:服務端的過期是真的過期,即服務器端的Session存儲的數據結構多久不可用了,默認是30分鐘。

既然我們知道了Session是在服務端進行管理的,那么或許你們看到這有幾個疑問,Session是在在哪創建的?Session是存儲在什么數據結構中?接下來帶領大家一起看一下Session是如何被管理的。

Session的管理是在容器中被管理的,什么是容器呢?Tomcat、Jetty等都是容器。接下來我們拿最常用的Tomcat為例來看下Tomcat是如何管理Session的。在ManageBase的createSession是用來創建Session的。

@Overridepublic Session createSession(String sessionId) { //首先判斷Session數量是不是到了最大值,最大Session數可以通過參數設置 if ((maxActiveSessions >= 0) && (getActiveSessions() >= maxActiveSessions)) { rejectedSessions++; throw new TooManyActiveSessionsException( sm.getString("managerBase.createSession.ise"), maxActiveSessions); }

// 重用或者創建一個新的Session對象,請注意在Tomcat中就是StandardSession // 它是HttpSession的具體實現類,而HttpSession是Servlet規范中定義的接口 Session session = createEmptySession();

// 初始化新Session的值 session.setNew(true); session.setValid(true); session.setCreationTime(System.currentTimeMillis()); // 設置Session過期時間是30分鐘 session.setMaxInactiveInterval(getContext().getSessionTimeout() * 60); String id = sessionId; if (id == null) { id = generateSessionId(); } session.setId(id);// 這里會將Session添加到ConcurrentHashMap中 sessionCounter++;

//將創建時間添加到LinkedList中,并且把最先添加的時間移除 //主要還是方便清理過期Session SessionTiming timing = new SessionTiming(session.getCreationTime(), 0); synchronized (sessionCreationTiming) { sessionCreationTiming.add(timing); sessionCreationTiming.poll(); } return session}

到此我們明白了Session是如何創建出來的,創建出來后Session會被保存到一個ConcurrentHashMap中??梢钥碨tandardSession類。

protected Map<string, session> www.jintianxuesha.com sessions = new ConcurrentHashMap&lt;&gt;();

到這里大家應該對Session有簡單的了解了。

> Session是存儲在Tomcat的容器中,所以如果后端機器是多臺的話,因此多個機器間是無法共享Session的,此時可以使用Spring提供的分布式Session的解決方案,是將Session放在了Redis中。

Token

Session是將要驗證的信息存儲在服務端,并以SessionId和數據進行對應,SessionId由客戶端存儲,在請求時將SessionId也帶過去,因此實現了狀態的對應。而Token是在服務端將用戶信息經過Base64Url編碼過后傳給在客戶端,每次用戶請求的時候都會帶上這一段信息,因此服務端拿到此信息進行解密后就知道此用戶是誰了,這個方法叫做JWT(Json Web Token)。

>?Token相比較于Session的優點在于,當后端系統有多臺時,由于是客戶端訪問時直接帶著數據,因此無需做共享數據的操作。

Token的優點

  • 簡潔:可以通過URL,POST參數或者是在HTTP頭參數發送,因為數據量小,傳輸速度也很快

  • 自包含:由于串包含了用戶所需要的信息,避免了多次查詢數據庫

  • 因為Token是以Json的形式保存在客戶端的,所以JWT是跨語言的

  • 不需要在服務端保存會話信息,特別適用于分布式微服務

JWT的結構

實際的JWT大概長下面的這樣,它是一個很長的字符串,中間用.分割成三部分

JWT是有三部分組成的

Header

是一個Json對象,描述JWT的元數據,通常是下面這樣子的

{ "alg": "HS256", "typ": "JWT"}

上面代碼中,alg屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ屬性表示這個令牌(token)的類型(type),JWT 令牌統一寫為JWT。最后,將上面的 JSON 對象使用 Base64URL 算法轉成字符串。

> JWT 作為一個令牌(token),有些場合可能會放到 URL(比如 api.example.com/?token=xxx)。Base64 有三個字符+、/和=,在 URL 里面有特殊含義,所以要被替換掉:=被省略、+替換成-,/替換成_ 。這就是 Base64URL 算法。

Payload

Payload部分也是一個Json對象,用來存放實際需要傳輸的數據,JWT官方規定了下面幾個官方的字段供選用。

  • iss (issuer):簽發人

  • exp (expiration time):過期時間

  • sub (subject):主題

  • aud (audience):受眾

  • nbf (Not Before):生效時間

  • iat (Issued At):簽發時間

  • jti (JWT ID):編號

當然除了官方提供的這幾個字段我們也能夠自己定義私有字段,下面就是一個例子

{ "name": "xiaoMing", "age": 14}

默認情況下JWT是不加密的,任何人只要在網上進行Base64解碼就可以讀到信息,所以一般不要將秘密信息放在這個部分。這個Json對象也要用Base64URL?算法轉成字符串

Signature

Signature部分是對前面的兩部分的數據進行簽名,防止數據篡改。

首先需要定義一個秘鑰,這個秘鑰只有服務器才知道,不能泄露給用戶,然后使用Header中指定的簽名算法(默認情況是HMAC SHA256),算出簽名以后將Header、Payload、Signature三部分拼成一個字符串,每個部分用.分割開來,就可以返給用戶了。

> HS256可以使用單個密鑰為給定的數據樣本創建簽名。當消息與簽名一起傳輸時,接收方可以使用相同的密鑰來驗證簽名是否與消息匹配。

Java中如何使用Token

上面我們介紹了關于JWT的一些概念,接下來如何使用呢?首先在項目中引入Jar包

compile('io.jsonwebtoken:jjwt:0.9.0')

然后編碼如下

//?簽名算法?,將對token進行簽名?SignatureAlgorithm?signatureAlgorithm?=?SignatureAlgorithm.HS256;?//?通過秘鑰簽名JWT?byte[]?apiKeySecretBytes?=?DatatypeConverter.parseBase64Binary("SECRET");?Key?signingKey?=?new?SecretKeySpec(apiKeySecretBytes,?signatureAlgorithm.getJcaName());?Map<String,Object>?claimsMap?=?new?HashMap<>();?claimsMap.put("name","xiaoMing");?claimsMap.put("age",14);?JwtBuilder?builderWithSercet?=?Jwts.builder()???????? .setSubject("subject")??????????.setIssuer("issuer")??????????.addClaims(claimsMap)??????????.signWith(signatureAlgorithm,?signingKey);System.out.printf(builderWithSercet.compact());

發現輸出的Token如下

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJzdWJqZWN0IiwiaXNzIjoiaXNzdWVyIiwibmFtZSI6InhpYW9NaW5nIiwiYWdlIjoxNH0.3KOWQ-oYvBSzslW5vgB1D-JpCwS-HkWGyWdXCP5l3Ko

此時在網上隨便找個Base64解碼的網站就能將信息解碼出來

總結

相信大家看到這應該對Cookie、Session、Token有一定的了解了,接下來再回顧一下重要的知識點。

  • Cookie是存儲在客戶端的

  • Session是存儲在服務端的,可以理解為一個狀態列表。擁有一個唯一會話標識SessionId。可以根據SessionId在服務端查詢到存儲的信息。

  • Session會引發一個問題,即后端多臺機器時Session共享的問題,解決方案可以使用Spring提供的框架。

  • Token類似一個令牌,無狀態的,服務端所需的信息被Base64編碼后放到Token中,服務器可以直接解碼出其中的數據。

GitHub代碼地址

參考文章

  • Cookies vs. Tokens: The Definitive Guide

  • 徹底弄懂session,cookie,token

  • 透視HTTP協議

  • Manager組件:Tomcat的Session管理機制解析

  • JSON Web Token 入門教程

  • SpringBoot集成JWT實現token驗證

    JSON Web Token - 在Web應用間安全地傳遞信息</string,object></string,>

    有道無術,術可成;有術無道,止于術

    歡迎大家關注Java之道公眾號

    好文章,我在看??

總結

以上是生活随笔為你收集整理的一文彻底搞懂Cookie、Session、Token到底是什么的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 国产91香蕉| 少妇性高潮视频 | 亚洲无人区码一码二码三码 | 国产ts三人妖大战直男 | 黄色一级片网站 | 亚洲综合区 | 不卡av网| 久久艹在线 | 91爱爱.com| 91私拍 | 日韩三级在线 | 无码国产伦一区二区三区视频 | 激情五月婷婷小说 | 国语对白对话在线观看 | av在线不卡免费 | 精品一区二区三区电影 | 日本丰满少妇做爰爽爽 | 精品视频 | 精品亚洲成人 | 亚洲制服丝袜在线播放 | 伊人色区 | 精品蜜桃一区二区三区 | 偷偷操不一样 | 日本韩国欧美中文字幕 | 四虎国产精品成人免费入口 | 欧日韩精品 | 成人免费一区二区 | 日韩亚洲欧美一区二区三区 | 亚洲最大激情网 | 看黄色小视频 | 日本www色| xxxxav| 免费日韩欧美 | 日韩一区二区视频在线观看 | 精品日韩一区 | 亚洲欧美另类视频 | 亚洲在线免费观看 | 亚洲人一区二区三区 | 丰满少妇一区二区三区视频 | 精品国产乱码久久久久久蜜臀 | 影音先锋中文字幕人妻 | 欧美日本高清视频 | 欧美日韩一区二区不卡 | 亚洲欧美大片 | 久热99 | x88av视频| 国产精品毛片久久久 | 国产毛片毛片 | 亚洲深爱 | 99精品久久久久久久 | 已满十八岁免费观看 | 麻豆精品国产传媒mv男同 | 国产极品在线播放 | 亚洲成人系列 | 国产精品xxxxx| 久久婷婷一区二区 | 在线观看高h| 国产精品一区二区免费视频 | 秋霞在线视频观看 | 免费h漫禁漫天天堂 | 丁香六月五月婷婷 | 久久久免费毛片 | 国产精品美女久久久久久久 | 伊人狠狠操 | 精品一区二区在线免费观看 | 国产中文字幕一区二区三区 | 黄色一级视频 | 久久精品人妻一区二区三区 | 一区二区日韩精品 | 国产精品欧美久久久久久 | 精品人妻午夜一区二区三区四区 | 可以在线观看的av网站 | 少妇极品熟妇人妻无码 | 日本少妇一区二区三区 | 日韩在线视频网站 | 国产成人av一区 | 天天插天天操天天干 | 精精国产xxxx视频在线 | 欧美黄色免费视频 | 9191在线视频 | 久久亚洲视频 | 日韩 欧美 国产 综合 | www操操操| 日韩中文字幕视频 | 99久久久无码国产精品不卡 | 好男人www社区 | 日本大尺度电影免费观看全集中文版 | 免费观看在线观看 | 人妻久久久一区二区三区 | 天天夜夜草 | 成人作爱视频 | 欧日韩在线视频 | 色婷婷综合久久久久中文一区二区 | 一级做a在线观看 | 国产精品乱码久久久久久 | 久久久久亚洲av无码专区 | 在线观看的免费 | 天堂√8在线中文 | 亚洲手机在线观看 |