亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

前后端常見的幾種鑒權方式(小結)

2024-05-06 16:53:59
字體:
來源:轉載
供稿:網友

最近在重構公司以前產品的前端代碼,擯棄了以前的session-cookie鑒權方式,采用token鑒權,忙里偷閑覺得有必要對幾種常見的鑒權方式整理一下。

目前我們常用的鑒權有四種:

  1. HTTP Basic Authentication
  2. session-cookie
  3. Token 驗證
  4. OAuth(開放授權)

一.HTTP Basic Authentication

   這種授權方式是瀏覽器遵守http協議實現的基本授權方式,HTTP協議進行通信的過程中,HTTP協議定義了基本認證認證允許HTTP服務器對客戶端進行用戶身份證的方法。

認證過程:

  1. 客戶端向服務器請求數據,請求的內容可能是一個網頁或者是一個ajax異步請求,此時,假設客戶端尚未被驗證,則客戶端提供如下請求至服務器:

  Get /index.html HTTP/1.0 
  Host:www.google.com

  2. 服務器向客戶端發送驗證請求代碼401,(WWW-Authenticate: Basic realm=”google.com”這句話是關鍵,如果沒有客戶端不會彈出用戶名和密碼輸入界面)服務器返回的數據大抵如下:

  HTTP/1.0 401 Unauthorised 
  Server: SokEvo/1.0 
  WWW-Authenticate: Basic realm=”google.com” 
  Content-Type: text/html 
  Content-Length: xxx

  3. 當符合http1.0或1.1規范的客戶端(如IE,FIREFOX)收到401返回值時,將自動彈出一個登錄窗口,要求用戶輸入用戶名和密碼。

  4. 用戶輸入用戶名和密碼后,將用戶名及密碼以BASE64加密方式加密,并將密文放入前一條請求信息中,則客戶端發送的第一條請求信息則變成如下內容:

  Get /index.html HTTP/1.0 
  Host:www.google.com 
  Authorization: Basic d2FuZzp3YW5n

注:d2FuZzp3YW5n表示加密后的用戶名及密碼(用戶名:密碼 然后通過base64加密,加密過程是瀏覽器默認的行為,不需要我們人為加密,我們只需要輸入用戶名密碼即可)

  5. 服務器收到上述請求信息后,將Authorization字段后的用戶信息取出、解密,將解密后的用戶名及密碼與用戶數據庫進行比較驗證,如用戶名及密碼正確,服務器則根據請求,將所請求資源發送給客戶端

效果: 

客戶端未未認證的時候,會彈出用戶名密碼輸入框,這個時候請求時屬于pending狀態,這個時候其實服務當用戶輸入用戶名密碼的時候客戶端會再次發送帶Authentication頭的請求。

后端,鑒權

認證成功:

后端,鑒權

server.js

let express = require("express");let app = express();  app.use(express.static(__dirname+'/public'));  app.get("/Authentication_base",function(req,res){    console.log('req.headers.authorization:',req.headers)    if(!req.headers.authorization){      res.set({        'WWW-Authenticate':'Basic realm="wang"'      });      res.status(401).end();    }else{      let base64 = req.headers.authorization.split(" ")[1];      let userPass = new Buffer(base64, 'base64').toString().split(":");      let user = userPass[0];      let pass = userPass[1];      if(user=="wang"&&pass="wang"){        res.end("OK");      }else{        res.status(401).end();      }    }  })  app.listen(9090)

index.html:

<!DOCTYPE html><html>  <head>    <meta charset="UTF-8">    <title>HTTP Basic Authentication</title>  </head>  <body>    <div></div>    <script src="js/jquery-3.2.1.js"></script>    <script>      $(function(){       send('./Authentication_base');      })      var send = function(url){            $.ajax({             url : url,             method : 'GET',           });      }    </script>  </body></html>

  當然有登陸就有注銷,我們會發現當我們認證成功后每次請求請求頭都會帶上Authentication及里面的內容,那么如何做到讓這次登陸失效的?

  網上查了半天,目前最有效的方式就是在注銷操作的時候,專門在服務器設置一個專門的注銷賬號,當接收到的Authentication信息為注銷用戶名密碼的時候糾就帶便注銷成功了,而客戶端在注銷操作的時候,手動的的去修改請求頭重的Authentication,將他設置未服務器默認的注銷賬號和密碼。

  通過上面的簡單講解 其實我們已經可以返現這種驗證方式的缺陷加密方式簡單,僅僅是base64加密,這種加密方式是可逆的。同時在每個請求的頭上都會附帶上用戶名和密碼信息,這樣在外網是很容易被嗅探器探測到的。

總結:

  正式因為這樣,這種加密方式一般多被用在內部安全性要求不高的的系統上,只是相對的多,總的來說現在使用這種鑒權比較少了。如果項目需要部署在公網上,這種方式不推薦,當然你也可以和SSL來加密傳輸,這樣會好一點,這個如果我后面有時間來研究一下。

二.session-cookie

第二種這個方式是利用服務器端的session(會話)和瀏覽器端的cookie來實現前后端的認證,由于http請求時是無狀態的,服務器正常情況下是不知道當前請求之前有沒有來過,這個時候我們如果要記錄狀態,就需要在服務器端創建一個會話(seesion),將同一個客戶端的請求都維護在各自得會會話中,每當請求到達服務器端的時候,先去查一下該客戶端有沒有在服務器端創建seesion,如果有則已經認證成功了,否則就沒有認證。 
session-cookie認證主要分四步: 
  1,服務器在接受客戶端首次訪問時在服務器端創建seesion,然后保存seesion(我們可以將seesion保存在內存中,也可以保存在redis中,推薦使用后者),然后給這個session生成一個唯一的標識字符串,然后在響應頭中種下這個唯一標識字符串。 
   2.簽名。這一步只是對sid進行加密處理,服務端會根據這個secret密鑰進行解密。(非必需步驟) 
  3.瀏覽器中收到請求響應的時候會解析響應頭,然后將sid保存在本地cookie中,瀏覽器在下次http請求de 請求頭中會帶上該域名下的cookie信息, 
   4.服務器在接受客戶端請求時會去解析請求頭cookie中的sid,然后根據這個sid去找服務器端保存的該客戶端的session,然后判斷該請求是否合法。

后端,鑒權

server.js(nodejs+express+seesion+redis)

var express = require('express');var RedisStore = require('connect-redis')(express.session);var app = express();var secret = "wang839305939"// 設置 Cookieapp.use(express.cookieParser(secret));// 設置 Sessionapp.use(express.session({ store: new RedisStore({  host: "127.0.0.1",  port: 6379,  db: "session_db" }), secret: secret}))app.get("/", function(req, res) { var session = req.session; session.time= session.time|| 0; var n = session.time++; res.send('hello, session id:' + session.id + ' count:' + n);});app.listen(9080);

三.Token 驗證

使用基于 Token 的身份驗證方法,大概的流程是這樣的:

  1. 客戶端使用用戶名跟密碼請求登錄 
  2. 服務端收到請求,去驗證用戶名與密碼 
  3. 驗證成功后,服務端會簽發一個 Token,再把這個 Token 發送給客戶端 
  4. 客戶端收到 Token 以后可以把它存儲起來,比如放在 Cookie 里或者 Local Storage 里 
  5. 客戶端每次向服務端請求資源的時候需要帶著服務端簽發的 Token 
  6. 服務端收到請求,然后去驗證客戶端請求里面帶著的 Token,如果驗證成功,就向客戶端返回請求的數據

  總的來說就是客戶端在首次登陸以后,服務端再次接收http請求的時候,就只認token了,請求只要每次把token帶上就行了,服務器端會攔截所有的請求,然后校驗token的合法性,合法就放行,不合法就返回401(鑒權失?。?/p>

  乍的一看好像和前面的seesion-cookie有點像,seesion-cookie是通過seesionid來作為瀏覽器和服務端的鏈接橋梁,而token驗證方式貌似是token來起到seesionid的角色。其實這兩者差別是很大的。 
  1. sessionid 他只是一個唯一標識的字符串,服務端是根據這個字符串,來查詢在服務器端保持的seesion,這里面才保存著用戶的登陸狀態。但是token本身就是一種登陸成功憑證,他是在登陸成功后根據某種規則生成的一種信息憑證,他里面本身就保存著用戶的登陸狀態。服務器端只需要根據定義的規則校驗這個token是否合法就行。 
  2. session-cookie是需要cookie配合的,居然要cookie,那么在http代理客戶端的選擇上就是只有瀏覽器了,因為只有瀏覽器才會去解析請求響應頭里面的cookie,然后每次請求再默認帶上該域名下的cookie。但是我們知道http代理客戶端不只有瀏覽器,還有原生APP等等,這個時候cookie是不起作用的,或者瀏覽器端是可以禁止cookie的(雖然可以,但是這基本上是屬于吃飽沒事干的人干的事)…,但是token 就不一樣,他是登陸請求在登陸成功后再請求響應體中返回的信息,客戶端在收到響應的時候,可以把他存在本地的cookie,storage,或者內存中,然后再下一次請求的請求頭重帶上這個token就行了。簡單點來說cookie-session機制他限制了客戶端的類型,而token驗證機制豐富了客戶端類型。 
   3. 時效性。session-cookie的sessionid實在登陸的時候生成的而且在登出事時一直不變的,在一定程度上安全就會低,而token是可以在一段時間內動態改變的。 
   4. 可擴展性。token驗證本身是比較靈活的,一是token的解決方案有許多,常用的是JWT,二來我們可以基于token驗證機制,專門做一個鑒權服務,用它向多個服務的請求進行統一鑒權。

下面就拿最常用的JWT(JSON WEB TOKEN)來說:

   JWT是Auth0提出的通過對JSON進行加密簽名來實現授權驗證的方案,就是登陸成功后將相關信息組成json對象,然后對這個對象進行某中方式的加密,返回給客戶端,客戶端在下次請求時帶上這個token,服務端再收到請求時校驗token合法性,其實也就是在校驗請求的合法性。 
JWT對象通常由三部分構成:

Headers: 包括類別(typ)、加密算法(alg)

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

Claims :包括需要傳遞的用戶信息

  {   "sub": "1234567890",   "name": "John Doe",   "admin": true  }

Signature: 根據alg算法與私有秘鑰進行加密得到的簽名字串, 這一段是最重要的敏感信息,只能在服務端解密;

HMACSHA256(   base64UrlEncode(Headers) + "." +  base64UrlEncode(Claims),  SECREATE_KEY)

編碼之后的JWT看起來是這樣的一串字符:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

nodejs+express+jwt-simple 

auth.js

let jwt = require('jwt-simple');let secret = "wangyy";let time = 10; module.exports = {  /* *檢驗token合法性 */  validate:function(req,res,next){    let token = req.body.token||req.headers["xssToken"];    if(token){      let decodeToken = null;     try { //防止假冒token解析報錯        decodeToken = jwt.decode(token,secret,'HS256');      } catch (err) {       res.status(401).send("非法訪問"); return;      }     let exp = decodeToken.exp; if(!exp){    res.status(401).send("非法訪問");   }   let now = new Date().getTime();   if(exp>(now+time*60*1000)){    res.send({code:'002',"errorMsg":"授權超時"})   }   next();  }else{     res.status(401).send("非法訪問");  } }, /* 生成token*/  makeToken(){    let Token = null;    let payload = {        time:new Date().getTime(),        exp:this.makeExp(time)        }    Token = jwt.encode(payload,secret,HS256) return Token;  },  /*生成token過期時間*/  makeExp:function(time){   let stam = time601000;   }  }

server.js

let express = require("express"); let app = express(); let bodyParser = require('body-parser'); let auth = require('./lib/auth.js'); let chalk = require('chalk'); app.use(bodyParser.json()); app.post('/login',function(req,res,next){       let Token = auth.makeToken();       res.json({result:"success",token:Token},200)  });app.use('*',[auth.validate],function(req,res,next){    res.send('success');  }); app.listen('9999')

  上面只是一個簡單的token生成和校驗,如果有需要可以根據實際需要進行邏輯處理

四.OAuth(開放授權)

  OAuth(開放授權)是一個開放標準,允許用戶授權第三方網站訪問他們存儲在另外的服務提供者上的信息,而不需要將用戶名和密碼提供給第三方網站或分享他們數據的所有內容,為了保護用戶數據的安全和隱私,第三方網站訪問用戶數據前都需要顯式的向用戶征求授權。我們常見的提供OAuth認證服務的廠商有支付寶,QQ,微信。 
  OAuth協議又有1.0和2.0兩個版本。相比較1.0版,2.0版整個授權驗證流程更簡單更安全,也是目前最主要的用戶身份驗證和授權方式。 

下面是一張auth2.0的流程圖: 

后端,鑒權

從圖中我們可以看出,auth2.0流程分為六布(我們就以csdn登陸為例):

第一步. 向用戶請求授權,現在很多的網站在登陸的時候都有第三方登陸的入口,當我們點擊等第三方入口時,第三方授權服務會引導我們進入第三方登陸授權頁面。

后端,鑒權

通過第三方請求授權頁面的瀏覽器地址欄地址可以看出,

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100270989&redirect_uri=https%3A%2F%2Fpassport.csdn.net%2Faccount%2Flogin%3Foauth_provider%3DQQProvider&state=test

這里的地址里面的%是瀏覽器強制編碼后的顯示我們可以使用decodeURIComponent進行解碼,解碼后是這樣:

https://graph.qq.com/oauth2.0/show?which=Login&display=pc&response_type=code&client_id=100270989&redirect_uri=https://passport.csdn.net/account/login?oauth_provider=QQProvider&state=test

這個url地址我們可以看見Auth2.0常見的幾個參數: 
      response_type,返回類型 
      client_id,第三方應用id,由授權服務器(qq)在第三方應用提交時頒發給第三方應用。 
      redirect_uri,登陸成功重定向頁面 
      oauth_provider,第三方授權提供方 
      state,由第三方應用給出的隨機碼 
第二步. 返回用戶憑證(code),并返回一個憑證(code),當用戶點擊授權并登陸后,授權服務器將生成一個用戶憑證(code)。這個用戶憑證會附加在重定向的地址redirect_uri的后面

https://passport.csdn.net/account/login?code=9e3efa6cea739f9aaab2&state=XXX

第3步. 請求授權服務器授權:

  經過第二部獲取code后后面的工作就可以交給后臺去處理的,和用戶的交互就結束了。接下來我的需要獲取Access Token,我們需要用他來向授權服務器獲取用戶信息等資源。 
  第三方應用后臺通過第二步的憑證(code)向授權服務器請求Access Token,這時候需要以下幾個信息:

  • client_id 標識第三方應用的id,由授權服務器(Github)在第三方應用提交時頒發給第三方應用
  • client_secret 第三方應用和授權服務器之間的安全憑證,由授權服務器(Github)在第三方應用提交時頒發給第三方應用
  • code 第一步中返回的用戶憑證redirect_uri 第一步生成用戶憑證后跳轉到第二步時的地址
  • state 由第三方應用給出的隨機碼

第四步. 授權服務器同意授權后,返回一個資源訪問的憑證(Access Token)。

第五步. 第三方應用通過第四步的憑證(Access Token)向資源服務器請求相關資源。

第六步. 資源服務器驗證憑證(Access Token)通過后,將第三方應用請求的資源返回。

從用戶角度來說,第三方授權可以讓我們快速的登陸應用,無需進行繁瑣的注冊,同時不用記住各種賬號密碼。只需要記住自己常用的幾個賬號就ok了。 
從產品經理的角度來所,這種授權方式提高用戶的體驗滿意度。另一方面可以獲取更多的用戶。

總結:

  授權方式多種多樣,主要還是要取決于我們對于產品的定位。如果我們的產品只是在企業內部使用,token和session就可以滿足我們的需求,如果是面向互聯網的大眾用戶,那么第三方授權在用戶體驗度上會有一個很大的提升。

  還是那句話,上面可能有很多‘通假字'勿怪,我寫作的目的一方面是希望和大家分享我掌握的點點滴滴,另一方面也是梳理一下掌握的知識。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本成人黄色片| 日韩在线视频网站| 色妞色视频一区二区三区四区| 日韩精品日韩在线观看| 国产精品吴梦梦| 日韩av电影在线播放| 欧美大尺度在线观看| 国产极品jizzhd欧美| 热久久美女精品天天吊色| 欧美亚洲国产视频小说| 91精品久久久久久久久久久久久| 欧美日韩精品在线视频| 亚洲免费电影在线观看| 亚洲自拍偷拍一区| 日本乱人伦a精品| 91久久在线播放| 日韩精品999| 日韩免费观看av| 亚洲视频一区二区| 国产精品稀缺呦系列在线| 97色在线视频观看| 日韩最新中文字幕电影免费看| 夜夜嗨av色综合久久久综合网| 97热精品视频官网| 色妞久久福利网| 久久久久久久电影一区| 永久免费毛片在线播放不卡| 91精品国产综合久久香蕉最新版| xvideos国产精品| 亚洲精品欧美日韩专区| 狠狠色狠狠色综合日日五| 久久五月天色综合| 欧美一区二区视频97| 亚洲欧美国产一区二区三区| 庆余年2免费日韩剧观看大牛| 自拍偷拍亚洲在线| 精品国内亚洲在观看18黄| 亚洲系列中文字幕| 亚洲va国产va天堂va久久| 久久久亚洲欧洲日产国码aⅴ| 国产香蕉一区二区三区在线视频| 成人激情av在线| 欧美激情一区二区三区在线视频观看| 久久久免费电影| 黄色91在线观看| 亚洲va欧美va国产综合久久| 色噜噜久久综合伊人一本| 日韩暖暖在线视频| 98视频在线噜噜噜国产| 国产小视频国产精品| 亚洲最大av网| 国产精品久久久久久久久久免费| 久久久免费观看视频| 精品中文字幕久久久久久| 91人人爽人人爽人人精88v| 2019国产精品自在线拍国产不卡| 欧美激情第6页| 81精品国产乱码久久久久久| 亚洲福利视频免费观看| 国产精品视频一| 国产精品视频最多的网站| 国产99久久精品一区二区 夜夜躁日日躁| 浅井舞香一区二区| 91sa在线看| 8090理伦午夜在线电影| 久久成人免费视频| 国产成人精品一区二区| 一区二区三区在线播放欧美| 欧美黑人性猛交| 久久久影视精品| 欧美成人精品在线| 亚洲精品资源美女情侣酒店| 日韩亚洲欧美中文在线| 亚洲欧美制服中文字幕| 欧美成人合集magnet| 亚洲护士老师的毛茸茸最新章节| 精品亚洲一区二区| 久久亚洲成人精品| 91精品综合久久久久久五月天| 欧美日韩国产123| 日韩精品在线观看一区| 国产精品91视频| 午夜伦理精品一区| 色中色综合影院手机版在线观看| 精品夜色国产国偷在线| 亚洲第一福利在线观看| 精品亚洲一区二区三区四区五区| 国产一区二区三区视频免费| 国产一区二区三区视频在线观看| 亚洲精品国产精品国产自| 海角国产乱辈乱精品视频| 色综合亚洲精品激情狠狠| 亚洲国产精彩中文乱码av| 亚洲人成在线一二| 久久国产精品久久国产精品| 亚洲春色另类小说| 亚洲激情 国产| 亚洲片国产一区一级在线观看| 国产网站欧美日韩免费精品在线观看| 91极品女神在线| 亚洲专区国产精品| 国产亚洲精品久久久久久| 国产成人精彩在线视频九色| 久久久女人电视剧免费播放下载| 欧美激情va永久在线播放| 91久久久久久久一区二区| 亚洲欧洲国产伦综合| 亚洲影视九九影院在线观看| 欧美日韩国产成人高清视频| 国产成人精品免费视频| 亚洲国产精品久久久久久| 欧美精品在线视频观看| 欧美成年人视频网站| 欧美精品aaa| 一道本无吗dⅴd在线播放一区| 欧美成人精品影院| 日韩精品免费视频| 亚洲精品美女视频| 6080yy精品一区二区三区| 欧美成人在线免费视频| 亚洲xxxxx性| 欧美成人精品在线视频| 91影院在线免费观看视频| 国产精品一二三在线| 毛片精品免费在线观看| 国产精品扒开腿做爽爽爽男男| 欧美二区乱c黑人| 国产精品一区二区av影院萌芽| 亚洲人成电影网站色xx| 久久久精品久久久| 最近2019年中文视频免费在线观看| 亚洲va久久久噜噜噜久久天堂| 日韩欧美国产激情| 国产精品高清免费在线观看| 青草青草久热精品视频在线网站| 日韩av电影手机在线观看| 久久精品中文字幕一区| 日韩亚洲第一页| 亚洲最大av网| 国产精品欧美风情| 亚洲欧美日韩一区在线| 成人综合网网址| 国产色视频一区| 国产精品女人网站| 神马国产精品影院av| 国产91色在线|免| 欧美日韩国产影院| 成人国产在线激情| 奇米4444一区二区三区| 在线成人一区二区| 亚洲深夜福利网站| 日韩成人中文字幕在线观看| 久久影视免费观看| 日本精品性网站在线观看| 亚洲天堂免费视频| 欧美中文字幕视频| 久久亚洲精品成人| 亚洲欧美日韩精品久久奇米色影视| 2018日韩中文字幕| 欧美成人精品不卡视频在线观看| 国产中文日韩欧美| 91久久夜色精品国产网站| 欧美精品一区二区三区国产精品| 国产精品69av|