最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

動(dòng)力節(jié)點(diǎn)SpringSecurity框架視頻教程-springsecurity+

2023-04-19 15:05 作者:摸魚協(xié)會(huì)秘書長  | 我要投稿

Base64及JWT學(xué)習(xí)筆記整理

老師的課件分享給大家咯~

1 base64編碼

1.1 什么是Base64

所謂Base64,就是說選出64個(gè)字符:小寫字母a-z、大寫字母A-Z、數(shù)字0-9、符號(hào)"+"、"/"(再加上作為墊字的"=",實(shí)際上是使用65個(gè)字符),作為一個(gè)基本字符集。然后,其他所有符號(hào)都轉(zhuǎn)換成這個(gè)字符集中的字符。

1.2 linux base64命令

1.2.1 Linux下用base64命令編解碼字符串

編碼:

echo -n 'Hello World' | base64

SGVsbG8gV29ybGQ=

解碼:

echo -n 'SGVsbG8gV29ybGQ=' | base64 -d

Hello World

備注:

??echo 命令是帶換行符的

??echo -n 不換行輸出

??echo -n '{"alg":"HS256","typ":"JWT"}' | base64

1.2.2 base64 編解碼文件

#base64編碼

# base64 待編碼的文件名 > 編碼后的文件名

base64 ?1.mp3 > mymp3

#base64 解碼

#base64 -d 待解碼的文件名 >解碼后的文件名

base64 -d mymp3>88.mp3

1.3 Base64和Base64Url 的區(qū)別

Base64Url是一種在Base64的基礎(chǔ)上編碼形成新的編碼方式,為了編碼能在網(wǎng)絡(luò)中安全順暢傳輸,需要對(duì)Base64進(jìn)行的編碼,特別是互聯(lián)網(wǎng)中。

Base64Url 編碼的流程:

?1、明文使用BASE64進(jìn)行編碼

?2、在Base64編碼的基礎(chǔ)上進(jìn)行以下的處理:

????1)去除尾部的"="

????2)把"+"替換成"-"

????3)斜線"/"替換成下劃線"_"

2 跨域認(rèn)證問題和JWT 實(shí)現(xiàn)登錄原理圖

2.1 跨域認(rèn)證問題

互聯(lián)網(wǎng)服務(wù)離不開用戶認(rèn)證。一般流程是下面這樣。

l?用戶向服務(wù)器發(fā)送用戶名和密碼。

l?服務(wù)器驗(yàn)證通過后,在當(dāng)前對(duì)話(session)里面保存相關(guān)數(shù)據(jù),比如用戶角色、登錄時(shí)間等等。

l?服務(wù)器向用戶返回一個(gè) jsession_id,寫入用戶的 Cookie。

l?用戶隨后的每一次請(qǐng)求,都會(huì)通過 Cookie,將 session_id 傳回服務(wù)器。

l?服務(wù)器收到 session_id,找到前期保存的數(shù)據(jù),由此得知用戶的身份。

這種模式的問題在于,擴(kuò)展性(scaling)不好。單機(jī)當(dāng)然沒有問題,如果是服務(wù)器集群,或者是跨域的服務(wù)導(dǎo)向架構(gòu),就要求 session 數(shù)據(jù)共享,每臺(tái)服務(wù)器都能夠讀取 session。

舉例來說,A 網(wǎng)站和 B 網(wǎng)站是同一家公司的關(guān)聯(lián)服務(wù)?,F(xiàn)在要求,用戶只要在其中一個(gè)網(wǎng)站登錄,再訪問另一個(gè)網(wǎng)站就會(huì)自動(dòng)登錄,請(qǐng)問怎么實(shí)現(xiàn)?

一種解決方案是 session 數(shù)據(jù)持久化,寫入數(shù)據(jù)庫或別的持久層。各種服務(wù)收到請(qǐng)求后,都向持久層請(qǐng)求數(shù)據(jù)。這種方案的優(yōu)點(diǎn)是架構(gòu)清晰,缺點(diǎn)是工程量比較大。另外,持久層萬一掛了,就會(huì)單點(diǎn)失敗。

另一種方案是服務(wù)器索性不保存 session 數(shù)據(jù)了,所有數(shù)據(jù)都保存在客戶端,每次請(qǐng)求都發(fā)回服務(wù)器。JWT 就是這種方案的一個(gè)代表。?服務(wù)器不存數(shù)據(jù),客戶端存,服務(wù)器解析就行了

2.2 JWT 實(shí)現(xiàn)登錄原理圖

說明:

JWT只通過算法實(shí)現(xiàn)對(duì)Token合法性的驗(yàn)證,不依賴數(shù)據(jù)庫,Memcached的等存儲(chǔ)系統(tǒng),因此可以做到跨服務(wù)器驗(yàn)證,只要密鑰和算法相同,不同服務(wù)器程序生成的Token可以互相驗(yàn)證。

3 JWT學(xué)習(xí)

3.1 簡介

JSON Web Token(JWT)是一個(gè)開放標(biāo)準(zhǔn)(RFC 7519),它定義了一種緊湊且獨(dú)立的方式,用于在各方之間作為JSON對(duì)象安全地傳輸信息。 此信息可以通過數(shù)字簽名進(jìn)行驗(yàn)證和信任。 JWT可以使用密鑰(使用HMAC算法)或使用RSA或ECDSA的公鑰/私鑰對(duì)進(jìn)行簽名。

??官方網(wǎng)址:https://jwt.io/

??調(diào)試頁面:https://jwt.io/

??學(xué)習(xí)文檔:https://jwt.io/introduction/

3.2 用途

??授權(quán):這是我們使用JWT最廣泛的應(yīng)用場(chǎng)景。一次用戶登錄,后續(xù)請(qǐng)求將會(huì)包含JWT,對(duì)于那些合法的token,允許用戶連接路由,服務(wù)和資源。目前JWT廣泛應(yīng)用在SSO(Single Sign On)(單點(diǎn)登錄)上。因?yàn)樗麄冮_銷很小并且可以在不同領(lǐng)域輕松使用。

??信息交換:JSON Web Token是一種在各方面之間安全信息傳輸?shù)暮玫姆绞?因?yàn)镴WT可以簽名 - 例如,使用公鑰/私鑰對(duì) - 您可以確定發(fā)件人是他們所說的人。 此外,由于使用標(biāo)頭和有效負(fù)載計(jì)算簽名,您還可以驗(yàn)證內(nèi)容是否未被篡改。

3.3 JWT組成

一個(gè)JWT由三部分組成,各部分以點(diǎn)分隔:

Header(頭部)-----base64Url編碼的Json字符串

Payload(載荷)---base64url編碼的Json字符串

Signature(簽名)---使用指定算法,通過Header和Playload加鹽計(jì)算的字符串

一個(gè)JWT看起來像下面這樣:

xxxxx.yyyyy.zzzzz

?

下面這樣:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c

3.3.1 Header

此部分有兩部分組成:

??一部分是token的類型,目前只能是JWT

??另一部分是簽名算法,比如HMAC 、 SHA256 、 RSA

示例:

{

??"alg":"HS256",

??"typ":"JWT"

}

base64編碼命令:

echo -n '{"alg":"HS256","typ":"JWT"}' | base64

?

3.3.2 Payload

token的第二部分是payload(有效負(fù)載),其中包含claims(聲明)。Claims是關(guān)于一個(gè)實(shí)體(通常是用戶)和其他數(shù)據(jù)類型的聲明。

claims有三種類型:registered,public,and private claims。

?

??Registered(已注冊(cè)的聲明):這些是一組預(yù)定義聲明,不是強(qiáng)制性的,但建議使用,以提供一組有用的,可互操作的聲明。 其中一些是:iss(發(fā)行人),exp(到期時(shí)間),sub(主題),aud(觀眾)and others。(請(qǐng)注意,聲明名稱只有三個(gè)字符,因?yàn)镴WT意味著緊湊。)

JWT 規(guī)定了7個(gè)官方字段,供選用。

iss (issuer):簽發(fā)人

exp (expiration time):過期時(shí)間

sub (subject):主題

aud (audience):受眾

nbf (Not Before):生效時(shí)間

iat (Issued At):簽發(fā)時(shí)間

jti (JWT ID):編號(hào)

除了官方字段,你還可以在這個(gè)部分定義私有字段,下面就是一個(gè)例子。

{

??"sub": "1234567890",

??"name": "John Doe",

??"admin": true

}

注意,JWT 默認(rèn)是不加密的,任何人都可以讀到,所以不要把秘密信息(密碼,手機(jī)號(hào)等)放在這個(gè)部分。

這個(gè) JSON 對(duì)象也要使用 Base64URL 算法轉(zhuǎn)成字符串。

?

?

?

??Public(公開聲明):這些可以由使用JWT的人隨意定義。 但為避免沖突,應(yīng)在IANA JSON Web Token Registry中定義它們,或者將其定義為包含防沖突命名空間的URI。

?

??private (私人聲明):這些聲明是為了在同意使用它們的各方之間共享信息而創(chuàng)建的,并且既不是注冊(cè)聲明也不是公開聲明。

示例:

{

??"sub": "1234567890",

??"name": "John Doe",

??"admin": true

}

3.3.3 Signature(保證數(shù)據(jù)安全性的)

Signature 部分是對(duì)前兩部分的簽名,防止數(shù)據(jù)篡改。

首先,需要指定一個(gè)密鑰(secret)。這個(gè)密鑰只有服務(wù)器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認(rèn)是 HMAC SHA256),按照下面的公式產(chǎn)生簽名。

?HMACSHA256(

??base64UrlEncode(header) + "." +

??base64UrlEncode(payload),

??secret)

算出簽名以后,把 Header、Payload、Signature 三個(gè)部分拼成一個(gè)字符串,每個(gè)部分之間用"點(diǎn)"(.)分隔,就可以返回給用戶。

?

示例:

HMACSHA256(

??base64UrlEncode(header) + "." +

??base64UrlEncode(payload),

??secret)

3.4 JWT 的使用方式【重點(diǎn)】

客戶端收到服務(wù)器返回的 JWT,可以儲(chǔ)存在 Cookie 里面,也可以儲(chǔ)存在 localStorage。

此后,客戶端每次與服務(wù)器通信,都要帶上這個(gè) JWT。你可以把它放在 Cookie 里面自動(dòng)發(fā)送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請(qǐng)求的頭信息Authorization字段里面。

Authorization: Bearer jwt

另一種做法是,跨域的時(shí)候,JWT 就放在 POST 請(qǐng)求的數(shù)據(jù)體里面。

3.5 JWT 的幾個(gè)特點(diǎn)

JWT 默認(rèn)是不加密,但也是可以加密的。生成原始 Token 以后,可以用密鑰再加密一次。

JWT 不加密的情況下,不能將秘密數(shù)據(jù)寫入 JWT。

JWT 不僅可以用于認(rèn)證,也可以用于交換信息。有效使用 JWT,可以降低服務(wù)器查詢數(shù)據(jù)庫的次數(shù)。

JWT 的最大缺點(diǎn)是,由于服務(wù)器不保存 session 狀態(tài),因此無法在使用過程中廢止某個(gè) token,或者更改 token 的權(quán)限。也就是說,一旦 JWT 簽發(fā)了,在到期之前就會(huì)始終有效,除非服務(wù)器部署額外的邏輯(JWT的登出問題)。就是因?yàn)榉?wù)端無狀態(tài)了

正常情況下 修改了密碼后就會(huì)跳轉(zhuǎn)到登錄頁面 :修改成功后清空瀏覽器保存的token了

后端怎么玩? 因?yàn)榉?wù)端不保留token 我用之前的token 還是可以繼續(xù)訪問的

從有狀態(tài)(后端也會(huì)存一個(gè))的變成無狀態(tài)的了

我們就要把它從無狀態(tài)再變成有狀態(tài)了

JWT 本身包含了認(rèn)證信息,一旦泄露,任何人都可以獲得該令牌的所有權(quán)限。為了減少盜用,JWT 的有效期應(yīng)該設(shè)置得比較短。對(duì)于一些比較重要的權(quán)限,使用時(shí)應(yīng)該再次對(duì)用戶進(jìn)行認(rèn)證。

為了減少盜用,JWT 不應(yīng)該使用 HTTP?80?協(xié)議明碼傳輸,要使用 HTTPS?443?協(xié)議傳輸。

?

我們頒發(fā)一個(gè)令牌?用戶名稱 用戶的權(quán)限信息??這個(gè)令牌2個(gè)小時(shí)有效

Jwt只要能解析 就認(rèn)為你是可用的??做不了 登出?后端不存儲(chǔ)用戶信息了 后端無狀態(tài)了

4 Java類庫



5 java中使用jwt

5.1 新建maven工程jwt-learn1

5.2 添加依賴

<!-- 添加jwt的依賴 -->

<dependency>

????<groupId>com.auth0</groupId>

????<artifactId>java-jwt</artifactId>

????<version>3.11.0</version>

</dependency>

5.3 編寫功能類

package com.powernode.utils;


import com.auth0.jwt.JWT;

import com.auth0.jwt.JWTVerifier;

import com.auth0.jwt.algorithms.Algorithm;

import com.auth0.jwt.exceptions.TokenExpiredException;

import com.auth0.jwt.interfaces.Claim;

import com.auth0.jwt.interfaces.DecodedJWT;


import java.util.Date;

import java.util.HashMap;

import java.util.List;

import java.util.Map;


/**

?* 用于生成和解析JWT

?*/

public class JWTUtils {


????/**

?????* 聲明一個(gè)秘鑰

?????*/

????private static final String SECRET = "leige";



????/**

?????* 生成JWT

?????*

?????* @param userId ??用戶編號(hào)

?????* @param username 用戶名

?????* @param auth ????用戶權(quán)限

?????*/

????public String createToken(Integer userId, String username, List<String> auth) {

????????//得到當(dāng)前的系統(tǒng)時(shí)間

????????Date currentDate = new Date();

????????//根據(jù)當(dāng)前時(shí)間計(jì)算出過期時(shí)間 定死為5分鐘

????????Date expTime = new Date(currentDate.getTime() + (1000 * 60 * 5));

????????//組裝頭數(shù)據(jù)

????????Map<String, Object> header = new HashMap<>();

????????header.put("alg", "HS256");

????????header.put("typ", "JWT");

????????return JWT.create()

????????????????.withHeader(header) //頭

????????????????.withClaim("userId", userId) //自定義數(shù)據(jù)

????????????????.withClaim("username", username) //自定義數(shù)據(jù)

????????????????.withClaim("auth", auth) //自定義數(shù)據(jù)

????????????????.withIssuedAt(currentDate) //創(chuàng)建時(shí)間

????????????????.withExpiresAt(expTime)//過期時(shí)間

????????????????.sign(Algorithm.HMAC256(SECRET));

????}


????/**

?????* 驗(yàn)證JWT并解析

?????*

?????* @param token 要驗(yàn)證的jwt的字符串

?????*/

????public static Boolean verifyToken(String token) {

????????try{

????????????// 使用秘鑰創(chuàng)建一個(gè)解析對(duì)象

????????????JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();

????????????//驗(yàn)證JWT

????????????DecodedJWT decodedJWT = jwtVerifier.verify(token);

// ???????????String header = decodedJWT.getHeader();

// ???????????String payload = decodedJWT.getPayload();

// ???????????String signature = decodedJWT.getSignature();

// ???????????System.out.println("header = " + header);

// ???????????System.out.println("payload = " + payload);

// ???????????System.out.println("signature = " + signature);

//

// ???????????Date expiresAt = decodedJWT.getExpiresAt();

// ???????????System.out.println("expiresAt = " + expiresAt);

// ???????????Claim userId = decodedJWT.getClaim("userId");

// ???????????System.out.println("userId = " + userId.asInt());

// ???????????Claim username = decodedJWT.getClaim("username");

// ???????????System.out.println("username = " + username.asString());

// ???????????Claim auth = decodedJWT.getClaim("auth");

// ???????????System.out.println("auth = " + auth.asList(String.class));

????????????return true;

????????}catch (TokenExpiredException e){

????????????e.printStackTrace();

????????}

????????return false;

????}


????/**

?????* 獲取JWT里面相前的用戶編號(hào)

?????*/

????public Integer getUserId(String token){

????????try{

????????????// 使用秘鑰創(chuàng)建一個(gè)解析對(duì)象

????????????JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();

????????????//驗(yàn)證JWT

????????????DecodedJWT decodedJWT = jwtVerifier.verify(token);

????????????Claim userId = decodedJWT.getClaim("userId");

????????????return userId.asInt();

????????}catch (TokenExpiredException e){

????????????e.printStackTrace();

????????}

????????return null;

????}

????/**

?????* 獲取JWT里面相前的用戶名

?????*/

????public static String getUsername(String token){

????????try{

????????????// 使用秘鑰創(chuàng)建一個(gè)解析對(duì)象

????????????JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();

????????????//驗(yàn)證JWT

????????????DecodedJWT decodedJWT = jwtVerifier.verify(token);

????????????Claim username = decodedJWT.getClaim("username");

????????????return username.asString();

????????}catch (TokenExpiredException e){

????????????e.printStackTrace();

????????}

????????return null;

????}

????/**

?????* 獲取JWT里面相前權(quán)限

?????*/

????public List<String> getAuth(String token){

????????try{

????????????// 使用秘鑰創(chuàng)建一個(gè)解析對(duì)象

????????????JWTVerifier jwtVerifier=JWT.require(Algorithm.HMAC256(SECRET)).build();

????????????//驗(yàn)證JWT

????????????DecodedJWT decodedJWT = jwtVerifier.verify(token);

????????????Claim auth = decodedJWT.getClaim("auth");

????????????return auth.asList(String.class);

????????}catch (TokenExpiredException e){

????????????e.printStackTrace();

????????}

????????return null;

????}


}

5.4 寫主類測(cè)試一下

6 JWT的總結(jié)

JWT就是一個(gè)加密的帶用戶信息的字符串,沒學(xué)習(xí)JWT之前,我們?cè)陧?xiàng)目中都是返回一個(gè)基本的字符串,然后請(qǐng)求時(shí)帶上這個(gè)字符串,再從session或者redis中(共享session)獲取當(dāng)前用戶,學(xué)過JWT以后我們可以把用戶信息直接放在字符串返回給前端,然后用戶請(qǐng)求時(shí)帶過來,我們是在服務(wù)器進(jìn)行解析拿到當(dāng)前用戶,這就是兩種登錄方式,這兩種方式有各自的優(yōu)缺點(diǎn)。

?

動(dòng)力節(jié)點(diǎn)SpringSecurity框架視頻教程-springsecurity+的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國家法律
宜州市| 包头市| 舞阳县| 临武县| 麻城市| 博爱县| 汝城县| 峨眉山市| 诸城市| 安新县| 将乐县| 伽师县| 荥经县| 同仁县| 即墨市| 金平| 拜城县| 新沂市| 南丰县| 衡阳县| 常德市| 龙川县| 定安县| 璧山县| 江阴市| 遂平县| 垦利县| 乐安县| 平武县| 东至县| 安庆市| 衢州市| 临安市| 辽宁省| 疏附县| 体育| 上思县| 柳河县| 夏河县| 贵溪市| 永福县|