亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Angular之jwt令牌身份驗證的實現

發布時間:2020-09-23 10:32:00 來源:腳本之家 閱讀:196 作者:FlyWine 欄目:web開發

Angular之jwt令牌身份驗證

demo https://gitee.com/powersky/jwt

介紹

Json web token (JWT), 是為了在網絡應用環境間傳遞聲明而執行的一種基于JSON的開放標準((RFC 7519).該token被設計為緊湊且安全的,特別適用于分布式站點的單點登錄(SSO)場景。JWT的聲明一般被用來在身份提供者和服務提供者間傳遞被認證的用戶身份信息,以便于從資源服務器獲取資源,也可以增加一些額外的其它業務邏輯所必須的聲明信息,該token也可直接被用于認證,也可被加密。

起源

在講 JWT 之前一定要講講基于 token 和 session 的區別。

傳統的session認證

http 協議本身是一種無狀態的協議,就是意味著如果用戶向我們的應用提供了用戶名和密碼來進行用戶認證,那么下一次請求時,用戶還要再一次進行用戶認證才行,因為根據http協議,我們并不能知道是哪個用戶發出的請求,所以為了讓我們的應用能識別是哪個用戶發出的請求,我們只能在服務器存儲一份用戶登錄的信息,這份登錄信息會在響應時傳遞給瀏覽器,告訴其保存為 cookie,以便下次請求時發送給我們的應用,這樣我們的應用就能識別請求來自哪個用戶了,這就是傳統的基于 session 認證。

但是這種基于 session 的認證使應用本身很難得到擴展,隨著不同客戶端用戶的增加,獨立的服務器已無法承載更多的用戶,而這時候基于 session 認證應用的問題就會暴露出來。

工作原理

當 client 通過用戶名、密碼請求server并通過身份認證后,server就會生成身份認證相關的 session 數據,并且保存在內存或者內存數據庫。并將對應的 sesssion_id返回給 client,client會把保存session_id(可以加密簽名下防止篡改)在cookie。此后client的所有請求都會附帶該session_id(畢竟默認會把cookie傳給server),以確定server是否存在對應的session數據以及檢驗登錄狀態以及擁有什么權限,如果通過校驗就該干嘛干嘛,否則就重新登錄。

前端退出的話就清cookie。后端強制前端重新認證的話就清或者修改session。

Angular之jwt令牌身份驗證的實現

優點與弊端

優點:

  • 相比JWT,最大的優勢就在于可以主動清除session。
  • session保存在服務器端,相對較為安全。
  • 結合cookie使用,較為靈活,兼容性較好。

弊端:

每個用戶經過我們的應用認證之后,我們的應用都要在服務端做一次記錄,以方便用戶下次請求的鑒別,通常而言session都是保存在內存中,而隨著認證用戶的增多,服務端的開銷會明顯增大。

用戶認證之后,服務端做認證記錄,如果認證的記錄被保存在內存中的話,這意味著用戶下次請求還必須要請求在這臺服務器上,這樣才能拿到授權的資源,這樣在分布式的應用上,相應的限制了負載均衡器的能力。這也意味著限制了應用的擴展能力。

如果是分布式部署,需要做多機共享session機制,實現方法可將session存儲到數據庫中或者redis

容易被CSRF,因為是基于cookie來進行用戶識別的, cookie如果被截獲,用戶就會很容易受到跨站請求偽造的攻擊。

cookie + session在跨域場景表現并不好

session、cookie、sessionStorage、localstorage的區別

session:

主要存放在服務器端,相對安全。

cookie:

可設置有效時間,默認是關閉瀏覽器后失效,主要存放在客戶端,并且不是很安全,可存儲大小約為4kb。

sessionStorage:

僅在當前會話下有效,關閉頁面或瀏覽器后被清除。

localstorage:

除非被清除,否則永久保存。

基于JWT token的驗證機制

JWT基本上由“.”分隔的三部分組成,分別是頭部,有效載荷和簽名。 一個簡單的JWT的例子,如下所示:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySUQiOjEsImlhdCI6MTU4MTMyMjE4MCwiZXhwIjoxNTgxMzI5MzgwfQ.6PVma3dLCbiXYgBJld5McFJ-q-QydCY7YVtrKPBsRi8

這部分字符串實際上是由三部分構成的,重點使用點符號分割的,在JWT中分別代表:Header、Payload、Signature。

Header

JWT 的 Header 通常包含兩個字段,分別是:typ(type) 和 alg(algorithm)。

typ: token的類型,這里固定為 JWT。

alg: 加密的算法,通常直接使用 HMAC SHA256

完整的頭部聲明如下:

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

然后將頭部進行base64加密(該加密是可以對稱解密的),構成了第一部分。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Playload

載荷就是存放有效信息的地方,這些有效信息包含如下三個部分:

  • 標準注冊聲明
  • 公共聲明
  • 私有聲明

標準注冊聲明

  • iss: jwt簽發者
  • sub: jwt所面向的用戶
  • aud: 接收jwt的一方
  • exp: jwt的過期時間,這個過期時間必須要大于簽發時間。
  • nbf: 定義在什么時間之前,該 JWT 都是不可用的。
  • iat: jwt的簽發時間
  • jti: jwt的唯一身份標識,主要用來作為一次性token,從而回避重放攻擊。

時間戳一般使用 unix 時間戳表示。

公共聲明

公共的聲明可以添加任何的信息,一般添加用戶的相關信息或其他業務需要的必要信息,但不建議添加敏感信息,因為該部分在客戶端可解密。

私有聲明

私有聲明是提供者和消費者所共同定義的聲明,一般不建議存放敏感信息,因為base64是對稱解密的,意味著該部分信息可以歸類為明文信息。

定義一個簡單的 payload,如下:

{
  userID: '1',
  exp: '1581329380',
  iat: '1581322180'
}

然后將其進行base64加密,得到JWT的第二部分。

eyJ1c2VySUQiOjEsImlhdCI6MTU4MTMyMjE4MCwiZXhwIjoxNTgxMzI5MzgwfQ

在線base64轉換工具 地址。

Signature

JWT的第三部分是一個簽證信息,這個簽證信息由三部分組成:

  • header (base64加密后的)
  • payload (base64加密后的)
  • secret

這個部分需要base64加密后的header和base64加密后的payload使用.連接組成的字符串,然后通過header中聲明的加密方式進行和secret組合加密,然后就構成了JWT的第三部分。

例如:

// javascript
var encodedString = base64UrlEncode(header) + '.' + base64UrlEncode(payload);

var signature = HMACSHA256(encodedString, 'secret');

secret是保存在服務器端的,JWT的簽發生成也是在服務器端的,secret就是用來進行JWT的簽發和JWT的驗證,所以,它就是你服務端的私鑰,在任何場景都不應該流露出去。一旦客戶端得知這個secret, 那就意味著客戶端是可以自我簽發JWT了,那么你的程序將可能會招到攻擊。

優點與弊端

優點:

  • 因為json的通用性,所以JWT是可以進行跨語言支持的,像JAVA,JavaScript,NodeJS,PHP等很多語言都可以使用。
  • 因為有了payload部分,所以JWT可以在自身存儲一些其他業務邏輯所必要的非敏感信息。
  • 便于傳輸,jwt的構成非常簡單,字節占用很小,所以它是非常便于傳輸的。
  • 它不需要在服務端保存會話信息, 所以它易于應用的擴展。

弊端:

  • 需要設計token續簽問題
  • 需要設計用戶退出后token依然有效等問題
  • 密碼修改后token依然有效等問題
  • 還有很多小問題,但是我覺得是利大于弊吧

一般是在請求頭里加入Authorization,并加上Bearer標注:

fetch('api/user/1', {
 headers: {
  'Authorization': 'Bearer ' + token
 }
})

工作原理如圖:

Angular之jwt令牌身份驗證的實現

Angular中使用JWT進行身份驗證

這里使用一TODO案例來進行演示。

設計API

  • /auth POST 提交用戶名 username 和密碼 password 進行登陸認證,返回 JWT 字符串。
  • /todos GET 返回待辦事項清單。
  • /todos/{id} GET 返回指定的待辦事項。
  • /users GET 返回用戶列表。

程序操作流程簡述

首先程序有一個登錄界面,用戶需要輸入用戶和用戶密碼。當提交表單后,前端會將數據發送到后端的 /auth 路徑。后端采取合適的查詢方式對這個用戶進行驗證,驗證成功后會返回token 字符串。

后端數據聲明

// 定義用戶
const USERS = [
  { id: 1, username: 'vincent', password: '123456'},
  { id: 2, username: 'bob', password: '123456'},
  { id: 3, username: 'peter', password: '123456'},
];

// 創建TODO列表,json格式
const TODOS = [
  { id: 1, userId: 1, name: "Play LOL", completed: false },
  { id: 2, userId: 1, name: "Do homework", completed: true },
  { id: 3, userId: 2, name: "Play basketball", completed: false },
  { id: 4, userId: 3, name: "Finish Angular JWT", completed: false },
];

密碼切記不能放在 payload 中的,因為這樣很不安全。

后端代碼實現

導入所需要的庫

const _ = require('lodash');
const express = require('express')
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const expressJwt = require('express-jwt');

定義函數

// 獲取用戶相關的所有Todo事項函數
function getTodos(userID) {
  var todos = _.filter(TODOS, ['userId', userID]);
  return todos;
}

// 獲取指定id的todo事項
function getTodo(todoID) {
  var todo = _.find(TODOS, (todo) => { return todo.id == todoID; })

  return todo;
}

// 獲取所有用戶
function getUsers() {
  let users = Array(USERS.length);
  for (let i = 0; i < USERS.length; i++) {
    users[i] = {id: USERS[i].id, username: USERS[i].username};
  }
  return users;
}

使用 expressJwt 生成 token

Angular之jwt令牌身份驗證的實現

todo-shared-secret是秘鑰字符串,這個注意一定要存儲在后端。
具體代碼可以到 https://gitee.com/powersky/jwt 這里來找。

實現其他的API

Angular之jwt令牌身份驗證的實現

前端代碼實現

前端主要分為以下幾個部分:

服務:

  • user service 用于獲取用戶數據
  • todo service 用于獲取todo數據
  • auth service 用于驗證用戶獲取token
  • auth guard 用于路由守衛,判斷是否能夠進行路由跳轉

組件:

  • user list 用戶展示界面
  • todo list 用戶展示todo待辦事項界面
  • login 用戶登錄界面

下面依次展示。

user.service.ts

Angular之jwt令牌身份驗證的實現

todo.service.ts

Angular之jwt令牌身份驗證的實現

auth.service.ts

Angular之jwt令牌身份驗證的實現

auth.guard.ts

Angular之jwt令牌身份驗證的實現

UserListComponenthtml

Angular之jwt令牌身份驗證的實現

Angular之jwt令牌身份驗證的實現

TodoListComponenthtml

Angular之jwt令牌身份驗證的實現

Angular之jwt令牌身份驗證的實現

LoginComponenthtml

Angular之jwt令牌身份驗證的實現

Angular之jwt令牌身份驗證的實現

AppComponenthtml

Angular之jwt令牌身份驗證的實現

Angular之jwt令牌身份驗證的實現

AppRoutingModule

Angular之jwt令牌身份驗證的實現

為了能夠使用代理需要增加一個配置文件:

proxy.conf.json

{
 "/api/*": {
  "target": "http://localhost:4000",
  "secure": false,
  "logLevel": "debug",
  "changeOrigin": true
 }
}

然后在package.json中加入:

"name": "jwt",
"version": "0.0.0",
"scripts": {
"ng": "ng",
"start": "ng serve --proxy-config proxy.conf.json",
"build": "ng build",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
},

然后命令行執行下面命令開啟前端:

npm start

執行下面命令啟動后端:

node server/app.js

到此這個案例就結束了。

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

寿阳县| 伊金霍洛旗| 宜城市| 临沭县| 永清县| 华宁县| 晋中市| 买车| 菏泽市| 韶山市| 桑日县| 九龙县| 伊宁市| 大荔县| 尼勒克县| 鸡西市| 保德县| 松原市| 石柱| 蓬溪县| 西平县| 盖州市| 盐源县| 广昌县| 通道| 临泉县| 灵宝市| 平利县| 阳新县| 吴旗县| 高阳县| 扎赉特旗| 揭西县| 会泽县| 城固县| 砚山县| 新竹市| 北川| 华池县| 大兴区| 西畴县|