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

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 综合教程 >内容正文

综合教程

关于 Token,你应该知道的十件事

發(fā)布時(shí)間:2023/12/29 综合教程 35 生活家
生活随笔 收集整理的這篇文章主要介紹了 关于 Token,你应该知道的十件事 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

轉(zhuǎn)自:http://ju.outofmemory.cn/entry/134189

原文是一篇很好的講述 Token 在 Web 應(yīng)用中使用的文章,而這是我和Special合作翻譯的譯文。

1. Token 應(yīng)該被保存起來(lái)(放到 local / session stograge 或者 cookies)

在單頁(yè)應(yīng)用程序中,有些用戶(hù)刷新瀏覽器后會(huì)帶來(lái)一些跟 token 相關(guān)的問(wèn)題。而解決方法很簡(jiǎn)單:你應(yīng)該把 token 保存到起來(lái):放到 session storage, local storage 或者是客戶(hù)端的 cookie 里。而瀏覽器不支持 session storage 時(shí)都應(yīng)該轉(zhuǎn)存到 cookies 里。

如果你想“我把 token 保存到 cookie ,不就跟以前沒(méi)有任何分別?”。可是在這種情況下你只是把 cookie 當(dāng)作一個(gè)儲(chǔ)存機(jī)制,而不是一種驗(yàn)證機(jī)制。(比如說(shuō),這個(gè) cookie 不會(huì)被 Web 框架用于用戶(hù)驗(yàn)證,所以沒(méi)有 XSRF 攻擊的危險(xiǎn))。

2. Tokens 除了像 cookie 一樣有有效期,而且你可以有更多的操作方法

Tokens 應(yīng)該有一個(gè)有效期(在JSON Web Tokens中是作為exp屬性),否則其他人只要登錄過(guò)一次就可以永遠(yuǎn)地通過(guò) API 的驗(yàn)證。Cookies 基于同樣的理由也有一個(gè)有效期。

在 Cookies 的使用中,有不同的選項(xiàng)可以控制 cookie 的生命周期:

. cookies 可以在瀏覽器關(guān)閉后刪除(session cookies);
. 另外你可以實(shí)現(xiàn)服務(wù)器端的檢查(通常由你使用的 Web 框架完成),還有也可以實(shí)現(xiàn)絕對(duì)有效期或彈性有效期(sliding window expiration);
. Cookies 可以帶有有效期地保存起來(lái)(瀏覽器關(guān)閉后也不刪除)。

而在 tokens 的使用中,一旦 token 過(guò)期,只需要重新獲取一個(gè)。你可以使用一個(gè)接口去刷新 token:

. 讓舊的 token 失效;
. 檢查這個(gè)用戶(hù)是不是還存在,權(quán)限是否被取消或者任何對(duì)你的程序來(lái)說(shuō)是有必要的;
. 得到一個(gè)更新了有效期的 token。

你甚至可以把 token 原來(lái)的發(fā)布時(shí)間也保存起來(lái),并且強(qiáng)制在兩星期后重新登錄什么的。

app.post('/refresh_token', function (req, res) {
  // verify the existing token
  var profile = jwt.verify(req.body.token, secret);

  // if more than 14 days old, force login
  if (profile.original_iat - new Date() > 14) { // iat == issued at
    return res.send(401); // re-logging
  }

  // check if the user still exists or if authorization hasn't been revoked
  if (!valid) return res.send(401); // re-logging

  // issue a new token
  var refreshed_token = jwt.sign(profile, secret, { expiresInMinutes: 60*5 });
  res.json({ token: refreshed_token });
});

如果你需要撤回 tokens(當(dāng) token 的生存期比較長(zhǎng)的時(shí)候這很有必要)那么你需要一個(gè) token 的生成管理器去作檢查。

3. Local / session storage 不會(huì)跨域工作,請(qǐng)使用一個(gè)標(biāo)記 cookie

如果你設(shè)置一個(gè) cookie 的域名為.yourdomain.com它將可以被youdomain.comapp.yourdomain.com獲取,這樣用戶(hù)登錄并且轉(zhuǎn)到app.yourdomain.com后也能很容易地從主域名找回這個(gè) cookie(假如你的是電商網(wǎng)站)。

而另一方面,保存在 local / session storage 的 tokens,就不能從不同的域名中讀取(甚至是子域名也不行)。那你能怎么做?

一個(gè)可能的選擇是,當(dāng)用戶(hù)通過(guò)app.yourdomain.com上面的驗(yàn)證時(shí)你生成一個(gè) token 并且作為一個(gè) cookie 保存到.yourdomain.com

$.post('/authenticate, function() {
  // store token on local/session storage or cookie
    ....

  // create a cookie signaling that user is logged in
  $.cookie('loggedin', profile.name, '.yourdomain.com');
});

然后,在youromdain.com中你可以檢查這個(gè) cookie 是不是已經(jīng)存在了,并且如果存在的話(huà)就轉(zhuǎn)到app.youromdain.com去。從這以后,這個(gè) token 將會(huì)對(duì)程序的子域名以及之后通常的流程都有效(直到這個(gè) token 超過(guò)有效期)。

不過(guò)這將會(huì)導(dǎo)致 cookie 存在但 token 被刪除了或其他意外情況的發(fā)生。在這種情況下,用戶(hù)將不得不重新登錄。但重要的是,像我們之前說(shuō)的,我們不會(huì)這個(gè)用 cookie 作為驗(yàn)證方法,只是作為一個(gè)存儲(chǔ)機(jī)制去支持存儲(chǔ)信息在不同的域名中。

4. 每個(gè) CORS(跨域資源共享)請(qǐng)求都會(huì)帶上預(yù)請(qǐng)求(Preflight request)

有些人指出 Authorization header 不是一個(gè)simple header,因此對(duì)于一個(gè)特定的 URLs 的所有請(qǐng)求都會(huì)帶上一個(gè)預(yù)請(qǐng)求。

OPTIONS https://api.foo.com/bar
GET https://api.foo.com/bar
   Authorization: Bearer ....

OPTIONS https://api.foo.com/bar2
GET https://api.foo.com/bar2
   Authorization: Bearer ....

GET https://api.foo.com/bar
   Authorization: Bearer ....

但這只會(huì)發(fā)生在你發(fā)送Content-Type:application/json時(shí)。不過(guò)這說(shuō)明已經(jīng)出現(xiàn)在絕大多數(shù)的程序中了。

一個(gè)小小的警告,theOPTIONS請(qǐng)求不會(huì)帶有 Authorization header 自身,所以你的網(wǎng)絡(luò)框架應(yīng)該支持區(qū)別對(duì)待OPTISON和后來(lái)的請(qǐng)求。(微軟的 IIS 因?yàn)槟承┰蚝孟駮?huì)有問(wèn)題)。

5. 當(dāng)你需要流傳送某些東西,請(qǐng)用 token 去獲取一個(gè)已簽名的請(qǐng)求。

當(dāng)使用 cookies 時(shí),你可以很容易開(kāi)始一個(gè)文件的下載或流傳送內(nèi)容。然而,在 tokens 的使用中,請(qǐng)求是通過(guò) XHR 完成的,你不能依賴(lài)于它。而解決方法應(yīng)該是像 AWS 那樣通過(guò)生成一個(gè)簽名了的請(qǐng)求,例如,Hawk Bewits 是一個(gè)很好的框架去啟用它:

Request:

POST /download-file/123
Authorization: Bearer...

Response:

ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja

這個(gè) ticket 是無(wú)狀態(tài)并且是基于 URL 的:host + path + query + headers + timestamp + HMAC,并且有一個(gè)有效期。所以它可以用于像只能在5分鐘內(nèi)去下載一個(gè)文件。

你然后可以轉(zhuǎn)到/download-file/123?ticket=lahdoiasdhoiwdowijaksjdoaisdjoasidja中去。服務(wù)器就會(huì)檢查這個(gè) ticket 是不是有效然后像正常一樣開(kāi)始下一步的服務(wù)。

6.XSS比XSRF要更容易防范

XSS 攻擊的原理是,攻擊者插入一段可執(zhí)行的 JavaScripts 腳本,該腳本會(huì)讀出用戶(hù)瀏覽器的 cookies 并將它傳輸給攻擊者,攻擊者得到用戶(hù)的 Cookies 后,即可冒充用戶(hù)。但是要防范 XSS 也很簡(jiǎn)單,在寫(xiě)入 cookies 時(shí),將HttpOnly設(shè)置為true,客戶(hù)端 JavaScripts 就無(wú)法讀取該 cookies 的值,就可以有效防范 XSS 攻擊。因?yàn)?Tokens 也是儲(chǔ)存在本地的 session storage 或者是客戶(hù)端的 cookies 中,也是會(huì)受到 XSS 攻擊。所以在使用 tokens 的時(shí)候,必須要考慮過(guò)期機(jī)制,不然攻擊者就可以永久持有受害用戶(hù)帳號(hào)。

相比 XSS,XSRF 的危害性更大,因?yàn)榇蠖鄶?shù) Web 框架都已經(jīng)內(nèi)置了 XSS 防范機(jī)制(例如在 Ruby on Rails 中,用戶(hù)的輸入在輸出的時(shí)候都會(huì)做轉(zhuǎn)義操作,攻擊者插入的腳本就無(wú)法執(zhí)行),對(duì)于大部分開(kāi)發(fā)者而言,甚至連 XSRF 都不知道是什么玩意,更別提防范了。XSRF 目前并不是每個(gè) Web 框架都有防范機(jī)制,因此開(kāi)發(fā)者更應(yīng)該留意 XSRF 。

7. 注意 token 的大小

Token 機(jī)制在每次請(qǐng)求 API 的時(shí)候,都需要帶上一個(gè)Authorization的 Http Header 。

# Token
GET /foo
Authorization: Bearer ...2kb token...
# Cookie
GET /foo
connect.sid: ...20 bytes cookie...

Token 的大小其實(shí)由你儲(chǔ)存在 token 中的信息量所決定,例如可能有nicknameopenid等開(kāi)發(fā)者另外加上的信息。

但是 session cookies 機(jī)制只需要一個(gè)字串作為用戶(hù)標(biāo)識(shí)即可(例如 PHP 的 PHPSESSIONID),其中關(guān)于用戶(hù)的信息都會(huì)直接儲(chǔ)存到服務(wù)端的數(shù)據(jù)庫(kù)中,當(dāng)用戶(hù)請(qǐng)求時(shí)才從數(shù)據(jù)庫(kù)中撈出來(lái)用。

當(dāng)然 Token 機(jī)制也可以仿照 session cookies 機(jī)制這么做了,也是個(gè)有效控制 token 大小的方法。

Token 中只保留關(guān)鍵的幾條身份標(biāo)識(shí)信息,其余都放到數(shù)據(jù)庫(kù)里面了,權(quán)限控制的時(shí)候再撈出。這樣做的好處是,開(kāi)發(fā)者可以完全掌控 token,因?yàn)殛P(guān)鍵信息都已經(jīng)是你代碼和數(shù)據(jù)庫(kù)中的一部分了,想怎么弄都可以了。

舉個(gè)例子:

GET /foo
Authorization: Bearer ……500 bytes token….
Then on the server:
app.use('/api',
  // 首先檢查 token;
  expressJwt({secret: secret}),

  // 然后再?gòu)臄?shù)據(jù)庫(kù)中撈出用戶(hù)信息。
  function(req, res, next) {
    req.user.extra_data = get_from_db();
    next();
  });

另外值得一提的是,你也可以把東西都丟 Cookies 里面(而不是只丟個(gè)身份標(biāo)識(shí)字串)。只要確保資料經(jīng)過(guò)了嚴(yán)格的加密,攻擊者無(wú)法利用,現(xiàn)在有些 Web 框架已經(jīng)有類(lèi)似機(jī)制,例如 Nodejs 的這個(gè)插件mozilla/node-client-sessions。

8. 有需要的話(huà),要加密并且簽名 token

雖然 TLS/SSL 機(jī)制可以隔絕大多數(shù)中間人攻擊,但是如果 token 中帶有了用戶(hù)的敏感信息,開(kāi)發(fā)者也應(yīng)該要加密這些信息。

使用 JWT(文中第 9 點(diǎn)) 可以加密 token,但是由于目前大多數(shù) Web 框架還未支持 JWT,所以可以使用 AES-CBC 算法加密 token。

app.post('/authenticate', function (req, res) {
  // 校驗(yàn)用戶(hù);

  // 加密 token;
  var encrypted = { token: encryptAesSha256('shhhh', JSON.stringify(profile)) };

  // 給加密后的 token 簽名;
  var token = jwt.sign(encrypted, secret, { expiresInMinutes: 60*5 });

  res.json({ token: token });
}

function encryptAesSha256 (password, textToEncrypt) {
  var cipher = crypto.createCipher('aes-256-cbc', password);
  var crypted = cipher.update(textToEncrypt, 'utf8', 'hex');
  crypted += cipher.final('hex');
  return crypted;
}

// 上面就是 encrypt-then-MAC (加密后簽名)做法。

當(dāng)然你也可以用文中的第 7 點(diǎn),直接將敏感信息丟數(shù)據(jù)庫(kù)中。

9. 將 JSON Web Tokens 應(yīng)用到 OAuth 2

OAuth 2 是一個(gè)解決身份驗(yàn)證的授權(quán)協(xié)議,并且廣泛地使用了 token 。

用戶(hù)通過(guò) OAuth 2 協(xié)議授權(quán)第三方應(yīng)用權(quán)限,然后服務(wù)器返回一個(gè)access_token給第三方應(yīng)用,通常也帶有scope參數(shù),第三方應(yīng)用通過(guò)帶上access_token請(qǐng)求服務(wù)器,可以在授權(quán)范圍(scope)內(nèi)調(diào)用 API。

一般來(lái)說(shuō),類(lèi)似這種 token 是不透明的,就是核心數(shù)據(jù)都儲(chǔ)存以 hash-table 結(jié)果儲(chǔ)存在服務(wù)器中,客戶(hù)端只持有一個(gè)令牌(access_token),任何人都可以用這個(gè)令牌在授權(quán)范圍(scope)內(nèi)調(diào)用服務(wù)器端的 API。

Signed tokens(例如JWT))和這種形式的 token 最主要的區(qū)別是,JWT 是無(wú)狀態(tài)的,它不儲(chǔ)存在服務(wù)端 hash-table 中,服務(wù)端中不保留 JWT 請(qǐng)求的相關(guān)信息,JWT 會(huì)把授權(quán)信息和 API 調(diào)用返回都丟一起返回給客戶(hù)端。

JWT 通常以 Base64 + AES 方式編碼傳輸。OAuth 2 協(xié)議也支持 JWT,因?yàn)?OAuth 2 并未限制 access_token 數(shù)據(jù)格式,你可以將 JWT 應(yīng)用在 OAuth 2 上。

10. Tokens 不是萬(wàn)能的解決方法,得根據(jù)你的需求自行采用

這些年來(lái),我們幫助過(guò)不少大公司實(shí)現(xiàn)了他們的以 Token 為基礎(chǔ)的驗(yàn)證授權(quán)架構(gòu)。曾經(jīng)有一家 10k + 員工,有著大量數(shù)據(jù)的公司,他們想實(shí)現(xiàn)一個(gè)中央權(quán)限管理系統(tǒng),其中有一個(gè)需要是某個(gè)員工只能讀取某個(gè)國(guó)家某個(gè)醫(yī)院某個(gè)床位的idname字段數(shù)據(jù),想想這樣的細(xì)粒度的權(quán)限管理是多么難實(shí)現(xiàn),無(wú)論是技術(shù)上還是行政上。

當(dāng)然采用 tokens 與否,得看大家的具體需求,但是,要忠告大家的是,不要什么內(nèi)容都寫(xiě)到 tokens 了,加之前想想有沒(méi)有這個(gè)必要。

總結(jié)

以上是生活随笔為你收集整理的关于 Token,你应该知道的十件事的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 99热免费在线 | 色综合天天综合网天天狠天天 | 亚洲精品456 | 99视频在线看 | 成人91免费视频 | 一炮成瘾1v1高h | 大尺度床戏揉捏胸视频 | 韩国久久久久 | 国产乱淫av片免费 | 午夜久久久久久久 | 亚洲国产精品毛片av不卡在线 | 日韩欧美三级在线观看 | 中文字幕亚洲色图 | av影视网 | 国产免费麻豆 | 日韩精品一卡 | 欧美精品一区在线 | 国产乱码久久久久久 | 一区二区亚洲 | 毛片成人网| 亚洲男女激情 | 婷婷激情图片 | 丰满人妻一区二区三区性色 | 无码人妻精品一区二区三区66 | 国产一区二区三区视频网站 | 99国产精品一区 | 天海翼中文字幕 | 超碰人人人 | 精品无码久久久久 | 91网站大全 | 久久久精品人妻一区二区三区色秀 | 在线波多野结衣 | 日韩一级 | 在线视频免费观看一区 | 天天搞夜夜 | 亚洲精品男人天堂 | 精品一性一色一乱农村 | 美女视频一区 | 亚洲1级片 | 特黄一区二区三区 | 色婷婷香蕉在线一区二区 | 久久精品麻豆 | 精品国产a| 国产艳俗歌舞表演hd | 欧美性大战久久久久久久蜜桃 | 美女扒开内裤让男人捅 | 亚洲一二区视频 | 97国产成人 | 国产精品久久久久久 | 无码人妻aⅴ一区二区三区69岛 | 久久无码人妻丰满熟妇区毛片 | 91视频区 | 免费看60分钟黄视频 | 91久久精品国产 | 麻豆网站在线播放 | 欧洲影院 | 在线看片亚洲 | 九九热国产在线 | 精品人妻无码中文字幕18禁 | 国产伦理自拍 | 天天视频污 | 日b视频在线观看 | 欧美日韩在线中文字幕 | 亚洲天堂福利视频 | 波多野一区二区三区 | 毛片一二三区 | 久久久久久久黄色 | 精品人妻一区二区三区在线视频 | 爱射综合 | 国产精品久久久久毛片大屁完整版 | 国产一级做a爰片久久毛片男男 | 男人天堂网在线视频 | 亚洲精品中文字幕 | 深爱婷婷网 | 99精品免费 | 欧美视频第一区 | 中文字幕一区二区在线播放 | 美国av一区二区 | 91精品婷婷国产综合久久蝌蚪 | 91网站免费观看 | 一级片黑人| 国产99精品| 偷偷操99 | 嫩草综合 | 奇米av在线| 蝌蚪久久| 亚洲av无码一区二区二三区软件 | 少妇偷人精品无码人妻 | 老司机精品导航 | 人妻少妇精品中文字幕av蜜桃 | 制服丝袜av在线 | 国产欧美日韩二区 | 精品国产免费人成在线观看 | 国产无玛 | 欧美交| 精彩视频一区二区三区 | 超碰在线日韩 | 欧美另类在线观看 | 少妇av网 |