摘要:前言本文將會從最基本的一種權限驗證說起,即,然后是基于和的權限驗證,最后則是和一次性密碼。由于它不依賴于,等任何外部因素,所以它是最簡單的權限驗證方法。當使用來進行權限驗證時,有以下幾點需要注意。
前言
本文將會從最基本的一種web權限驗證說起,即HTTP Basic authentication,然后是基于cookies和tokens的權限驗證,最后則是signatures和一次性密碼。
HTTP Basic authentication當客戶端發起一個請求時,它可以使用HTTP Basic authentication來提供一個用戶名和密碼,來進行權限驗證。
由于它不依賴于cookies,sessions等任何外部因素,所以它是最簡單的權限驗證方法。在使用它時,客戶端需要在每次請求時,都附帶上Authorization請求頭,用戶名和密碼都不會被加密,但是需要被格式化為以下結構:
用戶名和密碼由一個冒號連接,如username:password
這個字符串需進行Base64編碼
Basic關鍵字需被放置在這個編碼后的字符串的前面
例子:
curl --header "Authorization: Basic am9objpzZWNyZXQ=" my-website.com
在Node.js中實現它是非常簡單的,以下是一個通過Express中間件來實現的例子:
import basicAuth from "basic-auth"; function unauthorized(res) { res.set("WWW-Authenticate", "Basic realm=Authorization Required"); return res.send(401); }; export default function auth(req, res, next) { const {name, pass} = basicAuth(req) || {}; if (!name || !pass) { return unauthorized(res); }; if (name === "john" && pass === "secret") { return next(); } return unauthorized(res); };
當然,你也可以在更高層上實現它,如nginx。
HTTP Basic authentication雖然十分簡單,但仍有一些需要注意的地方:
用戶名和密碼在每次請求時都會被帶上,即使請求是通過安全連接發送的,這也是潛在的可能暴露它們的地方。
如果網站使用的加密方法十分弱,或者被破解,那么用戶名和密碼將會馬上泄露。
用戶通過這種方式進行驗證時,并沒有登出的辦法
同樣,登陸超時也是沒有辦法做到的,你只能通過修改用戶的密碼來模擬。
Cookies當服務端在響應HTTP請求時,它可以在響應頭里加上Set-Cookie頭。然后瀏覽器會將這個cookie保存起來,并在以后請求同源的地址時,在Cookie請求頭中附上這些cookie。
當使用cookies來進行權限驗證時,有以下幾點需要注意。
總是將cookies設為HttpOnly當設置cookies時,總是使用HttpOnly標識,這樣以來cookies就不能通過document.cookies獲取,用以減少被XSS攻擊可能性。
總是使用簽名(signed) cookies當使用簽名cookies時,服務器則可以判斷該cookie是否被客戶端更改過。
不足:
需要花費額外的功夫來抵御CSRF攻擊
與REST風格不匹配。因為它在一個無狀態協議里注入了狀態。
Tokens現今,JWT(JSON Web Token)無處不在。讓我們先來看看它到底長什么樣。
JWT由三部分組成:
Header,由token的類型和哈希算法組成
Payload,包含了內容主體
Signature,當你選擇HMAC SHA256算法時,它由HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)計算得出。
將你的Koa應用加上JWT僅需幾行代碼:
var koa = require("koa"); var jwt = require("koa-jwt"); var app = koa(); app.use(jwt({ secret: "very-secret" })); // Protected middleware app.use(function *(){ // content of the token will be available on this.state.user this.body = { secret: "42" }; });
例子:
curl --header "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ" my-website.com
如果你在寫提供給原生移動應用或單頁web應用的API,JWT是一個不錯的選擇。
不足:
需要額外的措施來防護XSS攻擊
Signatures不論是使用cookies還是token,如果你傳輸的內容被他人截獲,那么它們將可以很容易得偽裝成真實的用戶。
如果解決這個問題?當我們討論的是API之間的通信,而不是瀏覽器之間的通信時,有一個辦法。
當API的消費者發送一個需要權限驗證的請求時,你可以對整個請求用一個私鑰進行哈希。你可以使用的請求的內容有:
HTTP方法
請求路徑
HTTP頭
HTTP體
以及一個私鑰
API的消費者和提供者都必須持有相同的私鑰。在生成了signature之后,你必須將其加在query string或HTTP頭中。另外,還需附上一個時間戳,用于判斷過期。
當這么做時,即使你傳輸的內容暴露了,攻擊者也無法偽裝成真實用戶,因為它無法自己生成signature。
不足:
不能用于瀏覽器/客戶端中,只能用于API之間的通信中。
一次性密碼一次性密碼算法使用一個共享的密鑰和一個當前時間戳或計數器來生成一個一次性密碼:
基于時間的一次性密碼算法,使用一個當前時間的時間戳
基于HMAC的一次性密碼算法,使用一個計數器
這些方法被用于雙重認證(two-factor authentication)中:一個用戶輸入了用戶名和密碼,然后服務器和客戶端同時生成一個一次性密碼。
在Node.js中,使用notp實現它是相對簡單的。
不足:
如果共享密鑰被竊取,那么用戶的token將可以被偽造
該在何時選擇何種驗證方法?如果你只需支持一個web應用,那么cookies和tokens的實現都是可以的(cookies對XSRF的防護較好,而JWT則更易于防護XSS)。
如果你需要同時支持web應用和移動客戶端,那么請使用基于token的驗證。
如果你正在構建僅與其他API通信的API,那么就使用signatures。
最后原文鏈接:https://blog.risingstack.com/web-authentication-methods-explained/
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/91562.html
摘要:框架具有輕便,開源的優點,所以本譯見構建用戶管理微服務五使用令牌和來實現身份驗證往期譯見系列文章在賬號分享中持續連載,敬請查看在往期譯見系列的文章中,我們已經建立了業務邏輯數據訪問層和前端控制器但是忽略了對身份進行驗證。 重拾后端之Spring Boot(四):使用JWT和Spring Security保護REST API 重拾后端之Spring Boot(一):REST API的搭建...
showImg(https://segmentfault.com/img/bV6aHV?w=1280&h=800); 社區優秀文章 Laravel 5.5+passport 放棄 dingo 開發 API 實戰,讓 API 開發更省心 - 自造車輪。 API 文檔神器 Swagger 介紹及在 PHP 項目中使用 - API 文檔撰寫方案 推薦 Laravel API 項目必須使用的 8 個...
摘要:探究系統登錄驗證碼的實現后端掘金驗證碼生成類手把手教程后端博客系統第一章掘金轉眼間時間就從月份到現在的十一月份了。提供了與標準不同的工作方式我的后端書架后端掘金我的后端書架月前本書架主要針對后端開發與架構。 Spring Boot干貨系列總綱 | 掘金技術征文 - 掘金原本地址:Spring Boot干貨系列總綱博客地址:http://tengj.top/ 前言 博主16年認識Spin...
閱讀 2544·2021-11-24 10:20
閱讀 2392·2021-09-10 10:51
閱讀 3381·2021-09-06 15:02
閱讀 3114·2019-08-30 15:55
閱讀 2841·2019-08-29 18:34
閱讀 3080·2019-08-29 12:14
閱讀 1218·2019-08-26 13:53
閱讀 2931·2019-08-26 13:43