Spring Security + JWT学习
现在第三方登录已经很普遍了,随便哪个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 观看大体上的说明即可,比较难理解的我都是一行一行给了备注的