現在第三方登錄已經很普遍了,隨便哪個App都會有使用微信登錄,使用手機號碼登錄,或者使用支付寶登錄等功能...
下面我們就以使用微信登錄,做一個簡單的流程分析分析
開胃:JWT認識
在上面的Oauth2的認證流程中,我們就可以看出一些貓膩來:
在我們拿着令牌去用戶信息系統調用用戶的相關信息的時候,
用戶信息系統其實去請求了授權服務器,驗證l了該令牌的合法性
這樣每次認證都需要去調用授權服務器做一個令牌合法性驗證,顯得效率低下。
JWT令牌思想
JWT令牌場景運用
之前返回的令牌就是一個普通的令牌,使用了JWT之后,這個令牌彷佛變得有點意思了起來
用戶在授權服務器通過之后,會得到一個JWT令牌;
這個令牌中就已經包含了用戶相關的信息;
客戶端只需要攜帶該JWT令牌訪問資源服務器即可;
資源服務器會按照約定的算法自動完成令牌的校驗,這就就不用再去請求授權服務器了
流程我相信大家都已經看懂了,下面我們就來一點文的,解釋一下JWT
JWT簡單介紹
Json Web Token:JWT一共包含了三部分數據,這三部分數據通過.分割拼接而成的字符串,如:xxx.yyy.zzz
1.Header:頭部【JSON】,通常頭部有兩部份信息,我們可對頭部信息進行base64加密解密得到頭部信息
聲明類型,這是一個JWT
聲明加密算法:自定義(HMAC / RSA /...)
如下所示模樣,
{
"typ": "JWT",
"alg": "HS256"
}2.payload【JSON】:載荷,就是我們要寄存的數據,一般包含一下信息
用戶身份信息(采用bases加密,可解密,不建議存放過於敏感的信息)
注冊聲明:如該token的簽發時間,過期時間(exp),簽發人(iss)等信息
如下所示模樣:
{
"name": "456",
"admin": true
}3.Signature:簽名,是整個數據的認證信息,
一般根據前兩部的數據再加上服務器上的密鑰通過加密算法生成,用於驗證整個數據的完整性和可靠性
如下所示模樣:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)base64UrlEncode(header) :令牌的頭部分
base64UrlEncode(payload):令牌的載荷
secret :簽名所使用的密鑰
看到這里,腦子里一現,是不是可以實現單點登錄哦?就用載荷保存用戶的唯一id,其他服務豈不是就可以獲得用戶信息?
Spring Security + JWT的Demo
項目介紹
-
這里或許你就會有疑問了?為什么上面我們說了Oauth2,這里卻不小試牛刀呢?
-
因為 Oauth2一般運用與分布式項目中,需要單獨起一個服務做鑒權服務,而我並沒有想去搭建一套SpringCloud的想法
-
所以這里就借着網上的一點小資料,代碼也是模仿的別人的,我對它進行吸收並做下學習筆記順便分享出來
pom文件指定相關依賴
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.ninja.study</groupId>
<artifactId>security_demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>Ninja-Security</name>
<description>鞋破露腳尖兒</description> <properties>
<java.version>1.8</java.version>
</properties> <dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.10.7</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.10.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.10.7</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency> <dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build> </project>
application.yml配置
更正一下,mysql的驅動類后面更換為了:com.mysql.cj.jdbc.Driver 望周知!
Code:GitHub見
不好理解的地方做了特別詳細的說明,大家學習可自行下載即可:
項目說明望周知
自測結果先說明一下:
注冊用戶
用戶登錄:
用戶帶着token去訪問服務
然后就是項目源碼說明:TODO 觀看大體上的說明即可,比較難理解的我都是一行一行給了備注的