搭建SpringCloud Alibaba鉴权中心服务(详细教程)

鉴权中心服务

认识JWT

json web token 是一个开放的标准 ,它定义了一个种紧凑的,自包含的方式,用于作为json对象在各方之间安全的传输信息

  • 服务器鉴权完成之后 会生成 json 对象 发送给客户端,之后客户端和服务端传输数据都需要带上这个对象,服务器完全通过这个json对象认定客户端身份,为了防止篡改数据,服务端在生成的时候都会加上签名(加密的意思),服务器不保存session数据也就是无状态,更适合实现扩展
  • 那些环境可以考虑使用jwt呢?用户授权 ,信息交换

JWT组成部分

  • *Header :头部信息

Header 由两部分组成(Token类型,加密算法的名称),并且使用的是base64的编码

  • *Payload:我们想要传递的数据

Payload KV形式的诗数据 ,这里就是我们想要传递的信息(授权的话就是Token信息)

  • *Signature :签名

Signature 为了得到签名 首先我们得有编码过的Header 编码过的payload 和一个密钥。签名用的算法就是header中指定的那个,之后就会对他们签名

我们需要一个签名公式

HMACSHA245(base64UrlEncode(header)+<span>"."</span>+base64UrlEncode(payload),secret)

产生一个签名,返回一个字符串,返回给客户端,之后客户端每次访问都要带上这个字符串,进行鉴权

JWT使用 .号来连接 HHH.PPPP.SSSS

授权,鉴权设计

这里我们先不考虑 gateway 网关,后续会搭建,我们的重点放在中间和右边部分

搭建SpringCloud Alibaba鉴权中心服务(详细教程)

鉴权部分,我们独立实现公共的工具类,为什么?以下三点

  • JWT本质上是通过算法算出的加密字符串,也可以通过算法反向解析出来,他不依赖任何的框架,所以这个功能有可以单独提取出来的前提
  • 我们的电商系统包含多个微服务,很显然我们每个服务都需要鉴权,于是我们把这个方法提取出来,方便复用
  • 高性能鉴权,为什么不在授权中心做鉴权,首先他回头过http请求等一系列操作,我们在本地只用java的话 少去了很多步骤,性能得到倍数的增长

授权编码实现

我们创建新的一个服务来编写我们的鉴权中心

e-commerce-authority-center

导入相关的依赖

<span><<span>dependencies</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>com.alibaba.cloud<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>spring-cloud-starter-alibaba-nacos-discovery<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>2.2.3.RELEASE<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>org.springframework.boot<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>spring-boot-starter-data-jpa<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>mysql<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>mysql-connector-java<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>8.0.12<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>scope</span>></span>runtime<span>scope</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>com.hyc.ecommerce<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>e-commerce-mvc-config<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>1.0-SNAPSHOT<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>org.springframework.cloud<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>spring-cloud-starter-zipkin<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>org.springframework.kafka<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>spring-kafka<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>2.5.0.RELEASE<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>org.freemarker<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>freemarker<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>2.3.30<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>dependency</span>></span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>groupId</span>></span>cn.smallbun.screw<span>groupId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>artifactId</span>></span>screw-core<span>artifactId</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span><<span>version</span>></span>1.0.3<span>version</span>><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>dependency</span>><br><span>dependencies</span>>

导入好依赖之后我们 编写对应的配置,如注册到naocs 加入adminserver的监管,配置数据源等 这里我们使用jpa 来做orm

  • *配置编写
<span>server:</span><br>&#xA0;&#xA0;<span>port:</span>&#xA0;<span>7000</span><br>&#xA0;&#xA0;<span>servlet:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>context-path:</span>&#xA0;<span>/ecommerce-authority-center</span><br><br><span>spring:</span><br>&#xA0;&#xA0;<span>application:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>name:</span>&#xA0;<span>e-commerce-authority-center</span><br>&#xA0;&#xA0;<span>cloud:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>nacos:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>discovery:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>enabled:</span>&#xA0;<span>true</span>&#xA0;<span>#&#xA0;&#x5982;&#x679C;&#x4E0D;&#x60F3;&#x4F7F;&#x7528;&#xA0;Nacos&#xA0;&#x8FDB;&#x884C;&#x670D;&#x52A1;&#x6CE8;&#x518C;&#x548C;&#x53D1;&#x73B0;,&#xA0;&#x8BBE;&#x7F6E;&#x4E3A;&#xA0;false&#xA0;&#x5373;&#x53EF;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>server-addr:</span>&#xA0;<span>127.0</span><span>.0</span><span>.1</span><span>:8848</span>&#xA0;<span>#&#xA0;Nacos&#xA0;&#x670D;&#x52A1;&#x5668;&#x5730;&#x5740;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>#&#xA0;server-addr:&#xA0;127.0.0.1:8848,127.0.0.1:8849,127.0.0.1:8850&#xA0;#&#xA0;Nacos&#xA0;&#x670D;&#x52A1;&#x5668;&#x5730;&#x5740;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>namespace:</span>&#xA0;<span>1bc13fd5-843b-4ac0-aa55-695c25bc0ac6</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>metadata:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>management:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>context-path:</span>&#xA0;<span>${server.servlet.context-path}/actuator</span><br>&#xA0;&#xA0;<span>jpa:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>show-sql:</span>&#xA0;<span>true</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>hibernate:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>ddl-auto:</span>&#xA0;<span>none</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>properties:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>hibernate.show_sql:</span>&#xA0;<span>true</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>hibernate.format_sql:</span>&#xA0;<span>true</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>open-in-view:</span>&#xA0;<span>false</span><br>&#xA0;&#xA0;<span>datasource:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>#&#xA0;&#x6570;&#x636E;&#x6E90;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>url:</span>&#xA0;<span>jdbc:mysql://127.0.0.1:3306/imooc_e_commerce?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>username:</span>&#xA0;<span>root</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>password:</span>&#xA0;<span>root</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>type:</span>&#xA0;<span>com.zaxxer.hikari.HikariDataSource</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>driver-class-name:</span>&#xA0;<span>com.mysql.cj.jdbc.Driver</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>#&#xA0;&#x8FDE;&#x63A5;&#x6C60;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>hikari:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>maximum-pool-size:</span>&#xA0;<span>8</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>minimum-idle:</span>&#xA0;<span>4</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>idle-timeout:</span>&#xA0;<span>30000</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>connection-timeout:</span>&#xA0;<span>30000</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>max-lifetime:</span>&#xA0;<span>45000</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>auto-commit:</span>&#xA0;<span>true</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>pool-name:</span>&#xA0;<span>ImoocEcommerceHikariCP</span><br>&#xA0;&#xA0;<span>kafka:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>bootstrap-servers:</span>&#xA0;<span>127.0</span><span>.0</span><span>.1</span><span>:9092</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>producer:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>retries:</span>&#xA0;<span>3</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>consumer:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>auto-offset-reset:</span>&#xA0;<span>latest</span><br>&#xA0;&#xA0;<span>zipkin:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>sender:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>type:</span>&#xA0;<span>kafka</span>&#xA0;<span>#&#xA0;&#x9ED8;&#x8BA4;&#x662F;&#xA0;web</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>base-url:</span>&#xA0;<span>http://127.0.0.1:9411/</span><br><br><span>#&#xA0;&#x66B4;&#x9732;&#x7AEF;&#x70B9;</span><br><span>management:</span><br>&#xA0;&#xA0;<span>endpoints:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>web:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>exposure:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>include:</span>&#xA0;<span>'*'</span><br>&#xA0;&#xA0;<span>endpoint:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>health:</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>show-details:</span>&#xA0;<span>always</span>

配置完成之后,编写主启动类 @EnableJpaAuditing因为我们用到 自动加入创建时间和修改时间,所以我们需要打开 jpa的自动审计功能,不然会报错

<span>@EnableJpaAuditing</span>&#xA0;<span>//&#x5141;&#x8BB8;&#xA0;jpa&#xA0;&#x7684;&#x81EA;&#x52A8;&#x5BA1;&#x8BA1;</span><br><span>@SpringBootApplication</span><br><span>@EnableDiscoveryClient</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>AuthorityApplication</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>static</span>&#xA0;<span>void</span>&#xA0;<span>main</span><span>(String[]&#xA0;args)</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;SpringApplication.run(AuthorityApplication<span>.<span>class</span>,&#xA0;<span>args</span>)</span>;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}

test包下就测试环境是否正确

<span>/**<br>&#xA0;*&#xA0;&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#x6D4B;&#x8BD5;&#x5165;&#x53E3;<br>&#xA0;*&#xA0;&#x9A8C;&#x8BC1;&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#xA0;&#x73AF;&#x5883;&#x53EF;&#x7528;&#x6027;<br>&#xA0;*/</span><br><span>@SpringBootTest</span><br><span>@RunWith</span>(SpringRunner<span>.<span>class</span>)<br><span>public</span>&#xA0;<span>class</span>&#xA0;<span>AuthorityCenterApplicationTest</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Test</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>void</span>&#xA0;<span>conetextLoad</span><span>()</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}

环境ok之后

我们去测试 数据库操作是否可用

编写实体类ecommerceUser

<span>/*<br>&#xA0;*&#xA0;&#x7528;&#x6237;&#x8868;&#x5B9E;&#x4F53;&#x7C7B;&#x5B9A;&#x4E49;<br>&#xA0;*&#xA0;*/</span><br><span>@Entity</span><br><span>@EntityListeners</span>(AuditingEntityListener<span>.<span>class</span>)<br>@<span>Table</span>(<span>name</span>&#xA0;</span>=&#xA0;<span>"t_ecommerce_user"</span>)<br><span>@Data</span><br><span>@NoArgsConstructor</span><br><span>@AllArgsConstructor</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>EcommerceUser</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;&#x81EA;&#x589E;&#x7EC4;&#x4EF6;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Id</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@GeneratedValue</span>(strategy&#xA0;=&#xA0;GenerationType.IDENTITY)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"id"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;<span>long</span>&#xA0;id;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x7528;&#x6237;&#x540D;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"username"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;username;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;MD5&#xA0;&#x5BC6;&#x7801;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"password"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;password;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x989D;&#x5916;&#x7684;&#x4FE1;&#x606F;&#xA0;json&#xA0;&#x5B57;&#x7B26;&#x4E32;&#x5B58;&#x50A8;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"extra_info"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;extraInfo;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x81EA;&#x52A8;&#x52A0;&#x5165;&#x521B;&#x5EFA;&#x65F6;&#x95F4;&#xA0;&#x9700;&#x8981;&#x4E3B;&#x542F;&#x52A8;&#x7C7B;&#x7684;&#x6CE8;&#x89E3;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@CreatedDate</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"create_time"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;Date&#xA0;createTime;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x81EA;&#x52A8;&#x52A0;&#x5165;&#x66F4;&#x65B0;&#x65F6;&#x95F4;&#xA0;&#x9700;&#x8981;&#x4E3B;&#x542F;&#x52A8;&#x7C7B;&#x7684;&#x6CE8;&#x89E3;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@CreatedDate</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Column</span>(name&#xA0;=&#xA0;<span>"update_time"</span>,&#xA0;nullable&#xA0;=&#xA0;<span>false</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;Date&#xA0;updateTime;<br>}

有了实体类我们需要有数据操作的实现 于是编写Dao 接口

其实当我们创建接口的时候jpa就已经有了对应的基础增删改查的方法

搭建SpringCloud Alibaba鉴权中心服务(详细教程)

这里我们实现两个自定义查询方法

<span>/**<br>&#xA0;*&#xA0;EcommerceUserDao&#xA0;&#x63A5;&#x53E3;&#x5B9A;&#x4E49;<br>&#xA0;*/</span><br><span>public</span>&#xA0;<span><span>interface</span>&#xA0;<span>EcommerceUserDao</span>&#xA0;<span>extends</span>&#xA0;<span>JpaRepository</span><<span>EcommerceUser</span>,&#xA0;<span>Long</span>>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x6839;&#x636E;&#x7528;&#x6237;&#x540D;&#x67E5;&#x8BE2;&#xA0;EcommerceUser&#xA0;&#x5BF9;&#x8C61;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x7B49;&#x4E8E;&#xA0;select&#xA0;*&#xA0;form&#xA0;t_ecommerce_user&#xA0;where&#xA0;username=?<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>EcommerceUser&#xA0;<span>findByUsername</span><span>(String&#xA0;name)</span></span>;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x6839;&#x636E;&#x7528;&#x6237;&#x540D;&#x67E5;&#x8BE2;&#xA0;EcommerceUser&#xA0;&#x5BF9;&#x8C61;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x7B49;&#x4E8E;&#xA0;select&#xA0;*&#xA0;form&#xA0;t_ecommerce_user&#xA0;where&#xA0;username=?&#xA0;and&#xA0;password=?<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>EcommerceUser&#xA0;<span>findByUsernameAndPassword</span><span>(String&#xA0;name,&#xA0;String&#xA0;password)</span></span>;<br><br>}

之后创建 test service

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/4<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;EcommerceUser&#xA0;&#x76F8;&#x5173;&#x6D4B;&#x8BD5;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>@SpringBootTest</span><br><span>@RunWith</span>(SpringRunner<span>.<span>class</span>)<br>@<span>Slf4j</span><br><span>public</span>&#xA0;<span>class</span>&#xA0;<span>EcommerUserTest</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Autowired</span><br>&#xA0;&#xA0;&#xA0;&#xA0;EcommerceUserDao&#xA0;ecommerceUserDao;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x6D4B;&#x8BD5;&#xA0;&#xA0;&#x65B0;&#x589E;&#x4E00;&#x4E2A;&#x7528;&#x6237;&#x6570;&#x636E;&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Test</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>void</span>&#xA0;<span>createUserRecord</span><span>()</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;EcommerceUser&#xA0;ecommerceUser&#xA0;=&#xA0;<span>new</span>&#xA0;EcommerceUser();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x8BBE;&#x7F6E;&#x8981;&#x63D2;&#x5165;&#x7684;&#x4FE1;&#x606F;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setUsername(<span>"hyc@qq.com"</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setPassword(MD5.create().digestHex(<span>"123456"</span>));<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setExtraInfo(<span>"{}"</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x65E5;&#x5FD7;&#x6253;&#x5370;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"server&#xA0;user:[{}]"</span>,&#xA0;JSON.toJSON(ecommerceUserDao.save(ecommerceUser)));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x6D4B;&#x8BD5;&#xA0;&#x6211;&#x4EEC;&#x7F16;&#x5199;&#x7684;&#x81EA;&#x5B9A;&#x4E49;&#x65B9;&#x6CD5;&#xA0;&#x67E5;&#x8BE2;&#xA0;&#x521A;&#x624D;&#x521B;&#x5EFA;&#x7684;&#x65B0;&#x89D2;&#x8272;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Test</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>void</span>&#xA0;<span>SelectUserInfo</span><span>()</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;String&#xA0;username&#xA0;=&#xA0;<span>"hyc@qq.com"</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"select&#xA0;userinof:[{}]"</span>,&#xA0;JSON.toJSON(ecommerceUserDao.findByUsername(username)));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}

测试相关的 方法 新增用户啊 或者是 按条件查询用户 ,测试均通过

搭建SpringCloud Alibaba鉴权中心服务(详细教程)

生成RSA256的公钥 和 私钥 非对称加密算法

他通过 私钥加密 公钥解密来完成验证,目前很多的鉴权 都是 JWTRSA256的算法来加密鉴权的,如果了解不多,就是用RSA256就可以了

  • *编码

编写生成公钥密钥的测试类,创建 一些我们常用的VO对象 用来储存我们常用的一些变量,比如用户信息,公钥,密钥,一些常用的属性 放进 VO的模型里

<span>@Slf</span>4j<br><span>@SpringBootTest</span><br><span>@RunWith</span>(SpringRunner<span>.<span>class</span>)<br>/**<br>&#xA0;*<br>&#xA0;*&#xA0;@<span>author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;@<span>date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;@<span>context</span>:&#xA0;<span>RSA</span>&#xA0;&#x975E;&#x5BF9;&#x79F0;&#xA0;&#x52A0;&#x5BC6;&#x7B97;&#x6CD5;<br>&#xA0;*&#xA0;@<span>params</span>&#xA0;:&#xA0;&#xA0;<span>null</span>&#xA0;<br>&#xA0;*&#xA0;@<span>return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;@<span>return</span>&#xA0;:&#xA0;<span>null</span><br>&#xA0;*/<br><span>public</span>&#xA0;<span>class</span>&#xA0;<span>RSATest</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Test</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>void</span>&#xA0;<span>generateKeyBytes</span><span>()</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x83B7;&#x53D6;&#x5230;&#xA0;RSA&#x7B97;&#x6CD5;&#x5B9E;&#x4F8B;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;KeyPairGenerator&#xA0;keyPairGenerator&#xA0;=&#xA0;KeyPairGenerator.getInstance(<span>"RSA"</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;&#x8FD9;&#x91CC;&#x6700;&#x5C0F;&#x662F;&#xA0;2048&#xA0;&#x4F4E;&#x4E8E;&#x7684;&#x8BDD;&#xA0;&#x662F;&#x4F1A;&#x62A5;&#x9519;&#x7684;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;keyPairGenerator.initialize(<span>2048</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x751F;&#x6210;&#x516C;&#x94A5;&#x5BF9;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;KeyPair&#xA0;keyPair&#xA0;=&#xA0;keyPairGenerator.generateKeyPair();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x83B7;&#x53D6;&#xA0;&#x516C;&#x94A5;&#x548C;&#x79C1;&#x94A5;&#x5BF9;&#x8C61;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;RSAPublicKey&#xA0;publicKey&#xA0;=&#xA0;(RSAPublicKey)&#xA0;keyPair.getPublic();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;RSAPrivateKey&#xA0;privateKey&#xA0;=&#xA0;(RSAPrivateKey)&#xA0;keyPair.getPrivate();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"private&#xA0;key:[{}]"</span>,&#xA0;Base64.encode(privateKey.getEncoded()));<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"public&#xA0;key:[{}]"</span>,&#xA0;Base64.encode(publicKey.getEncoded()));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}
  • *创建VO对象保存 我们常用且不会变化的值和对象

存储私钥 应为是私钥 所以只对鉴权中心 暴露 于是我们在鉴权服务中创建Constant包创建这个AuthotityConstant类保存信息

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;&#x9274;&#x6743;&#x7684;&#x5E38;&#x91CF;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>AuthorCanstant</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x79C1;&#x94A5;&#xA0;&#x53EA;&#x66B4;&#x9732;&#x7ED9;&#xA0;&#x9274;&#x6743;&#x4E2D;&#x5FC3;&#xA0;&#x4E0D;&#x66B4;&#x9732;&#x7ED9;&#x4EFB;&#x4F55;&#x7684;&#x5176;&#x4ED6;&#x670D;&#x52A1;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>public</span>&#xA0;<span>static</span>&#xA0;<span>final</span>&#xA0;String&#xA0;PRIVATE_KEY&#xA0;=&#xA0;<span>"MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBA"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"QCMXrQCudalKHJlH16YHr9mI5/xyYnkp5u2gAbMFf2xAHAyykYmixJP3CqG2a8tUwiJjjTIJXP+79Jzgjgg"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"VbBaTakrvjeFXz9HNP1D4XD6Li+sRVjnN1iBUwIFRxiFN2EOJflA9bqeQLAge/LgAu06y3jdLLleJF7yDRuMH"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"YedqPl9AJa5RdJmt0OgCoVOqacB7oGkFCFISm0Cwjfgq06nyiiULGZNVt8uhDxZAE4Pi2lmf3yggXCBH9AtU/2"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"XdyxU9caQJOAbYGxd/mART/NivBjSqo60wcBnktI+booUbDKRBbWRxvfYqKWEwPOwxlJUB3l3pcLZm866Xl3qtVM"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"XAgMBAAECggEADCGjLRkik+OK/3JWmo8Nu6YYjKz+XeSecIdgDwNXiZSgHcOdjHc4fe5pPn5RxXkHo9vGdAXIoJ/Z"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"cGIwt5qwQx2zITSvV7eDoIPT36n8OaMEO79Cj7kYzRR/eDVMyTagDLj7ccHK/yJYFnaf5vxZxFsRdwwGeTxreD"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"/pwZJLxjRSz1W57v5yUJNPPimNB229EogNYHIhQ8+Z7OGiilbtBIL9r6lqlz2hUAVBzXl4kOXFVI+vEodLuV2"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"rtQXXrpO1+AgH5lZJ7ahShKbqHt/Q6uJSTKAhbsfv/iadcPjmYp2F7nnYBLf66Jln6AWUwnXrJ7XETOf/+Qcib"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"q/5m6RjAQKBgQDruxn+kaDr5uYQMVSHog+CBRBJghJ4JklhY7ZDYJ2wN2KNHOd3mW/wUVDihVIyRFniIzsWU"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"0lnI+4OLqNLAZOBaQB5VrjyH4fxn5b26t0xLO1d5EWcOYI8ZRhwWDWaZipe2dUMeqVVMYFeDdTdNsyGrf8x"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"L+OVyRDiH4s4pBIs7QKBgQCYcIVFgDbrmwsP7lA9/dU9kClutY3gjEUgB2IJp2Y8S4Xhfi4NC8GqRQoMUyuqg"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"vPHKEiTCa1EojGHS/+r4JVcSg9Wsv64SpGZ+gANxRhfYFPrbkjU4YOMaZeCGUfKR2QnD20c3I4gdQ9kU5nK52n+Y"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"JEkAFUejg1Mhb6Fp6HDkwKBgAHYYBa3CxxtnUVpLXE2Woq5AWyh4QUhv5dMkYOrgPB9Ln9OR52PDOpDqK9tP"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"bx4/n8fqXm+QyfUhyuDP/H5XC86JC/O9vmmN4kzp5ndMsgMwvrmK4lShet1GyDd/+VqgVBmwh0r5JlrHske"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"sJjesfEn8YRwDIcCoOg0OQHDfwTtAoGAQfE61YvXNihFqsiOkaKCYjVAlxGWpDJJnMdU05REl4ScD6WDy"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"kTxq/RdmmNIGmS3i8mTS3f+Khh3kG2B1ho6wkePRxP7OEGZpqAM8ef22RtUch2tB9neDBmJXtAMzCYB3xu/O"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"aL3IHdDB0Va2/krUsz3PDmgmK0ed6HLfwm64l0CgYB+iGkMAQEwqYmcCEXKK825Q9y/u8PE9y8uaMGfsZQzDo6v"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"V5v+reOhmZRrk5BnX+pgztbE28sS6c2vYR0RYoR90aD2GXungCPXWEMDQudHFxvSsNTCYkDynjTSlnzu9aDcfqw1"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"UIzHog2zCquSro7tnbOMsvV5UdsLBq+WNQGgAw=="</span>;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x9ED8;&#x8BA4;&#x7684;&#xA0;token&#xA0;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#xFF0C;&#x4E00;&#x5929;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>public</span>&#xA0;<span>static</span>&#xA0;<span>final</span>&#xA0;Integer&#xA0;DEFAULT_EXPIRE_DAY&#xA0;=&#xA0;<span>1</span>;<br>}

之后是创建一些公共常用的VO模型 e-commerce-common

  • *保存 公钥到公用包 以后我们的服务 需要做授权都需要使用到
<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;&#x901A;&#x7528;&#x6A21;&#x5757;&#x7684;&#x5E38;&#x91CF;&#x5B9A;&#x4E49;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>CommonCanstant</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;RSA&#xA0;&#x516C;&#x94A5;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>public</span>&#xA0;<span>static</span>&#xA0;<span>final</span>&#xA0;String&#xA0;PUBLIC_KEY&#xA0;=&#xA0;<span>"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAjF60ArnWpShyZ"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"R9emB6/ZiOf8cmJ5KebtoAGzBX9sQBwMspGJosST9wqhtmvLVMIiY40yCVz/u/Sc4I4IFWwWk2pK743hV8/RzT9Q+F"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"w+i4vrEVY5zdYgVMCBUcYhTdhDiX5QPW6nkCwIHvy4ALtOst43Sy5XiRe8g0bjB2Hnaj5fQCWuUXSZrdDoAqFTqmnA"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"e6BpBQhSEptAsI34KtOp8oolCxmTVbfLoQ8WQBOD4tpZn98oIFwgR/QLVP9l3csVPXGkCTgG2BsXf5gEU/zYrwY0qqO"</span>&#xA0;+<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"tMHAZ5LSPm6KFGwykQW1kcb32KilhMDzsMZSVAd5d6XC2ZvOul5d6rVTFwIDAQAB"</span>;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;JWT&#xA0;&#x4E2D;&#xA0;&#x5B58;&#x50A8;&#x7528;&#x6237;&#x4FE1;&#x606F;&#x5230;&#xA0;key*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>public</span>&#xA0;<span>static</span>&#xA0;<span>final</span>&#xA0;String&#xA0;JWT_USER_INFO_KEY&#xA0;=&#xA0;<span>"e-commerce-user"</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#x7684;&#xA0;service-id*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>public</span>&#xA0;<span>static</span>&#xA0;<span>final</span>&#xA0;String&#xA0;AUTHORITY_CENTER_SERVICE_ID&#xA0;=&#xA0;<span>"e-commerce-authity-center"</span>;<br>}
  • *用户信息的常用VO对象

JwtToken

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#xA0;&#x9274;&#x6743;&#xA0;&#x4E4B;&#x540E;&#x7ED9;&#x5BA2;&#x6237;&#x7AEF;&#x7684;token<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>@Data</span><br><span>@NoArgsConstructor</span><br><span>@AllArgsConstructor</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>JwtToken</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#xA0;JWT*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;token;<br><br><br>}

LoginUserinfo

<span>@Data</span><br><span>@NoArgsConstructor</span><br><span>@AllArgsConstructor</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>LoginUserinfo</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x7528;&#x6237;&#xA0;id*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;Long&#xA0;id;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x7528;&#x6237;&#x540D;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;username;<br>}

UsernameAndPassword

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#x7528;&#x6237;&#x540D;&#x548C;&#x5BC6;&#x7801;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>@Data</span><br><span>@AllArgsConstructor</span><br><span>@NoArgsConstructor</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>UsernameAndPassword</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x7528;&#x6237;&#x540D;&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;username;<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x5BC6;&#x7801;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;String&#xA0;password;<br>}
  • *授权服务编写

首先创建一个 接口 IJWTService

定义我们需要实现的授权方法

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;JWT&#xA0;&#x76F8;&#x5173;&#x670D;&#x52A1;&#x63A5;&#x53E3;&#x5B9A;&#x4E49;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>public</span>&#xA0;<span><span>interface</span>&#xA0;<span>IJWTService</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x751F;&#x6210;&#xA0;token&#xA0;&#x4F7F;&#x7528;&#x9ED8;&#x8BA4;&#x7684;&#x8D85;&#x65F6;&#x65F6;&#x95F4;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>String&#xA0;<span>generateToken</span><span>(String&#xA0;username,&#xA0;String&#xA0;password)</span>&#xA0;<span>throws</span>&#xA0;Exception</span>;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x751F;&#x6210;&#xA0;JWT&#xA0;Token&#xA0;&#x53EF;&#x4EE5;&#x8BBE;&#x7F6E;&#x8D85;&#x65F6;&#x65F6;&#x95F4;&#xA0;&#x5355;&#x4F4D;&#x662F;&#x5929;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>String&#xA0;<span>generateToken</span><span>(String&#xA0;username,&#xA0;String&#xA0;password,&#xA0;Integer&#xA0;expireTime)</span>&#xA0;<span>throws</span>&#xA0;Exception</span>;<br><br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x6CE8;&#x518C;&#x7528;&#x6237;&#x5E76;&#x4E14;&#x751F;&#x6210;&#xA0;token&#xA0;&#x8FD4;&#x56DE;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>String&#xA0;<span>registerUserAndGenerateToken</span><span>(UsernameAndPassword&#xA0;usernameAndPassword)</span>&#xA0;<span>throws</span>&#xA0;Exception</span>;<br>}
  • *授权方法实现类

这里我们有三个方法实现

  • 默认超时时间的 生成 token
  • 自定义超时时间的设置生成token
  • 注册新用户并且生成的token返回

JWT对象生成细节:

1) 我们需要设置需要传递的对象

2)我们需要设置一个不重复的 id

3)我们需要设置超时时间

4)设置我们的加密签名

5)完成设置返回字符串对象

Jwts.builder()<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x8FD9;&#x91CC;&#xA0;claim&#xA0;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#xA0;jwt&#xA0;&#x7684;&#xA0;payload&#xA0;&#x5BF9;&#x8C61;&#xA0;-->&#xA0;KV</span><br>&#xA0;&#xA0;&#xA0;&#xA0;.claim(CommonCanstant.JWT_USER_INFO_KEY,&#xA0;JSON.toJSONString(loginUserinfo))<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;jwt&#xA0;id&#xA0;&#x8868;&#x793A;&#x662F;&#xA0;jwt&#x7684;id</span><br>&#xA0;&#xA0;&#xA0;&#xA0;.setId(UUID.randomUUID().toString())<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>//jwt&#xA0;&#x7684;&#x8FC7;&#x671F;&#x65F6;&#x95F4;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;.setExpiration(expireDate)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;&#x8FD9;&#x91CC;&#x662F;&#x8BBE;&#x7F6E;&#x52A0;&#x5BC6;&#x7684;&#x79C1;&#x94A5;&#x548C;&#x52A0;&#x5BC6;&#x7C7B;&#x578B;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;.signWith(getPrivateKey(),&#xA0;SignatureAlgorithm.RS256)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x751F;&#x6210;&#xA0;jwt&#x4FE1;&#x606F;&#xA0;&#x8FD4;&#x56DE;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x4E32;&#x7C7B;&#x578B;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;.compact();<br>&#xA0;&#xA0;&#xA0;&#xA0;}
  • *完整代码
<span>@Service</span><br><span>@Slf</span>4j<br><span>@Transactional</span>(rollbackFor&#xA0;=&#xA0;Exception<span>.<span>class</span>)<br><span>public</span>&#xA0;<span>class</span>&#xA0;<span>IJWTServiceIpml</span>&#xA0;<span>implements</span>&#xA0;<span>IJWTService</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Autowired</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;EcommerceUserDao&#xA0;ecommerceUserDao;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Override</span><br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;String&#xA0;<span>generateToken</span><span>(String&#xA0;username,&#xA0;String&#xA0;password)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;generateToken(username,&#xA0;password,&#xA0;<span>0</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Override</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;String&#xA0;<span>generateToken</span><span>(String&#xA0;username,&#xA0;String&#xA0;password,&#xA0;Integer&#xA0;expireTime)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x9996;&#x5148;&#x9700;&#x8981;&#x9A8C;&#x8BC1;&#x7528;&#x6237;&#x662F;&#x5426;&#x901A;&#x8FC7;&#x6388;&#x6743;&#x6821;&#x9A8C;&#xFF0C;&#x5373;&#xA0;&#x8F93;&#x5165;&#x7684;&#x7528;&#x6237;&#x540D;&#x548C;&#x5BC6;&#x7801;&#x80FD;&#x5426;&#x5BFB;&#x627E;&#x5230;&#x5339;&#x914D;&#x6570;&#x636E;&#x8868;&#x7684;&#x8BB0;&#x5F55;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;EcommerceUser&#xA0;ecommerceUser&#xA0;=&#xA0;ecommerceUserDao.findByUsernameAndPassword(username,&#xA0;password);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>if</span>&#xA0;(ecommerceUser&#xA0;==&#xA0;<span>null</span>)&#xA0;{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.error(<span>"can not find user&#xFF1A;[{}],[{}]"</span>,&#xA0;username,&#xA0;password);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>null</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//Token&#xA0;&#x4E2D;&#x585E;&#x5165;&#x5BF9;&#x8C61;&#xFF0C;&#xA0;&#x5373;&#xA0;JWT&#x4E2D;&#xA0;&#x50A8;&#x5B58;&#x7684;&#x5BF9;&#x8C61;&#xFF0C;&#x540E;&#x7AEF;&#x62FF;&#x5230;&#x8FD9;&#x4E9B;&#x4FE1;&#x606F;&#xA0;&#x5C31;&#x53EF;&#x4EE5;&#x77E5;&#x9053;&#x90A3;&#x4E2A;&#x7528;&#x6237;&#x5728;&#x64CD;&#x4F5C;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;LoginUserinfo&#xA0;loginUserinfo&#xA0;=&#xA0;<span>new</span>&#xA0;LoginUserinfo(<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.getId(),&#xA0;ecommerceUser.getUsername()<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;);<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>if</span>&#xA0;(expireTime&#xA0;<= <span>0)&#xA0;{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;expireTime&#xA0;=&#xA0;AuthorCanstant.DEFAULT_EXPIRE_DAY;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x8BA1;&#x7B97;&#x8D85;&#x65F6;&#x65F6;&#x95F4;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ZonedDateTime&#xA0;zdt&#xA0;=&#xA0;LocalDate.now().plus(expireTime,&#xA0;ChronoUnit.DAYS)<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.atStartOfDay(ZoneId.systemDefault());<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;Date&#xA0;expireDate&#xA0;=&#xA0;Date.from(zdt.toInstant());<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;Jwts.builder()<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x8FD9;&#x91CC;&#xA0;claim&#xA0;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#xA0;jwt&#xA0;&#x7684;&#xA0;payload&#xA0;&#x5BF9;&#x8C61;&#xA0;-->&#xA0;KV</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.claim(CommonCanstant.JWT_USER_INFO_KEY,&#xA0;JSON.toJSONString(loginUserinfo))<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;jwt&#xA0;id&#xA0;&#x8868;&#x793A;&#x662F;&#xA0;jwt&#x7684;id</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.setId(UUID.randomUUID().toString())<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//jwt&#xA0;&#x7684;&#x8FC7;&#x671F;&#x65F6;&#x95F4;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.setExpiration(expireDate)<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;&#x8FD9;&#x91CC;&#x662F;&#x8BBE;&#x7F6E;&#x52A0;&#x5BC6;&#x7684;&#x79C1;&#x94A5;&#x548C;&#x52A0;&#x5BC6;&#x7C7B;&#x578B;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.signWith(getPrivateKey(),&#xA0;SignatureAlgorithm.RS256)<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x751F;&#x6210;&#xA0;jwt&#x4FE1;&#x606F;&#xA0;&#x8FD4;&#x56DE;&#x7684;&#x662F;&#x4E00;&#x4E2A;&#x5B57;&#x7B26;&#x4E32;&#x7C7B;&#x578B;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;.compact();<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Override</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;String&#xA0;<span>registerUserAndGenerateToken</span><span>(UsernameAndPassword&#xA0;usernameAndPassword)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x5148;&#x53BB;&#x6821;&#x9A8C;&#xA0;&#x7528;&#x6237;&#x540D;&#x662F;&#x5426;&#x5B58;&#x5728;&#xA0;&#x5982;&#x679C;&#x5B58;&#x5728;&#xA0;&#x4E0D;&#x80FD;&#x91CD;&#x590D;&#x6CE8;&#x518C;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;EcommerceUser&#xA0;oldUser&#xA0;=&#xA0;ecommerceUserDao.findByUsername(usernameAndPassword.getUsername());<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>if</span>&#xA0;(<span>null</span>&#xA0;!=&#xA0;oldUser)&#xA0;{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.error(<span>"username&#xA0;is&#xA0;registered:[{}]"</span>,&#xA0;oldUser.getUsername());<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>null</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;EcommerceUser&#xA0;ecommerceUser&#xA0;=&#xA0;<span>new</span>&#xA0;EcommerceUser();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setUsername(usernameAndPassword.getUsername());<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setPassword(usernameAndPassword.getPassword());&#xA0;<span>//MD5&#xA0;&#x7F16;&#x7801;&#x4EE5;&#x540E;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser.setExtraInfo(<span>"{}"</span>);<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x6CE8;&#x518C;&#x4E00;&#x4E2A;&#x65B0;&#x7528;&#x6237;&#xA0;&#x5199;&#x5230;&#x4E00;&#x4E2A;&#xA0;&#x8BB0;&#x5F55;&#x8868;&#x4E2D;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;ecommerceUser&#xA0;=&#xA0;ecommerceUserDao.save(ecommerceUser);<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"regiter&#xA0;user&#xA0;success:[{}],[{}]"</span>,&#xA0;ecommerceUser.getUsername());<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x751F;&#x6210;&#xA0;token&#xA0;&#x5E76;&#x4E14;&#x8FD4;&#x56DE;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;generateToken(ecommerceUser.getUsername(),&#xA0;ecommerceUser.getPassword());<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x6839;&#x636E;&#x672C;&#x5730;&#x50A8;&#x5B58;&#x7684;&#x79C1;&#x94A5;&#x83B7;&#x53D6;&#x5230;&#xA0;PrivateKey&#x5BF9;&#x8C61;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>private</span>&#xA0;PrivateKey&#xA0;<span>getPrivateKey</span><span>()</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x4F7F;&#x7528;&#x7ED9;&#x5B9A;&#x7684;&#x7F16;&#x7801;&#x5BC6;&#x94A5;&#x521B;&#x5EFA;&#x4E00;&#x4E2A;&#x65B0;&#x7684;PKCS8EncodedKeySpec&#x3002;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;PKCS8EncodedKeySpec&#xA0;priPKCS8&#xA0;=&#xA0;<span>new</span>&#xA0;PKCS8EncodedKeySpec(<span>new</span>&#xA0;BASE64Decoder().decodeBuffer(AuthorCanstant.PRIVATE_KEY));<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;&#x8BBE;&#x7F6E;&#x751F;&#x6210;&#x65B0;&#x5BC6;&#x94A5;&#x7684;&#x5DE5;&#x5382;&#x52A0;&#x5BC6;&#x65B9;&#x5F0F;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;KeyFactory&#xA0;keyFactory&#xA0;=&#xA0;KeyFactory.getInstance(<span>"RSA"</span>);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x8FD4;&#x56DE;&#x751F;&#x6210;&#x597D;&#x7684;&#x5BC6;&#x94A5;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;keyFactory.generatePrivate(priPKCS8);<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}<br></= <span>

之后我们的授权都会使用到以上的方法

  • *Controller

我们需要给注册用户和生成token 一个程序的入口

就是我们的 AuthorityController,这里可以用到我们之前使用的注解@IgnoreResponseAdvice我们为啥那么不让他封装呢,我们需要验证,单纯的 JwtToken对象就可以了,不需要封装和转化

<span>@Slf</span>4j<br><span>@RestController</span><br><span>@RequestMapping</span>(<span>"/authority"</span>)<br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>AuthorityConroller</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;<span>final</span>&#xA0;IJWTService&#xA0;ljwtService;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>AuthorityConroller</span><span>(IJWTService&#xA0;ljwtService)</span>&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>this</span>.ljwtService&#xA0;=&#xA0;ljwtService;<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x4ECE;&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#xA0;&#x83B7;&#x53D6;&#xA0;token&#xA0;&#xFF08;&#x5176;&#x5B9E;&#x5C31;&#x662F;&#x767B;&#x9646;&#x529F;&#x80FD;&#xFF09;&#xA0;&#x4E14;&#x8FD4;&#x56DE;&#x4FE1;&#x606F;&#x4E2D;&#x6CA1;&#x6709;&#x7EDF;&#x4E00;&#x54CD;&#x5E94;&#x7684;&#x5305;&#x88C5;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@IgnoreResponseAdvice</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@PostMapping</span>(<span>"/token"</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;JwtToken&#xA0;<span>token</span><span>(@RequestBody&#xA0;UsernameAndPassword&#xA0;usernameAndPassword)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x901A;&#x5E38;&#xA0;&#x65E5;&#x5FD7;&#x91CC;&#x4E0D;&#x4F1A;&#x7B54;&#x6253;&#x5370;&#x7528;&#x6237;&#x7684;&#x4FE1;&#x606F;&#xA0;&#x9632;&#x6B62;&#x6CC4;&#x9732;&#xFF0C;&#x6211;&#x4EEC;&#x8FD9;&#x672C;&#x8EAB;&#x5C31;&#x662F;&#x4E00;&#x4E2A;&#x6388;&#x6743;&#x670D;&#x52A1;&#x5668;&#xFF0C;&#x672C;&#x8EAB;&#x5C31;&#x4E0D;&#x5BF9;&#x5916;&#x5F00;&#x653E;&#xFF0C;&#x6240;&#x4EE5;&#x6211;&#x4EEC;&#x53EF;&#x4EE5;&#x6253;&#x5370;&#x7528;&#x6237;&#x4FE1;&#x606F;&#x5230;&#x65E5;&#x5FD7;&#x65B9;&#x4FBF;&#x67E5;&#x770B;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"request&#xA0;to&#xA0;get&#xA0;token&#xA0;with&#xA0;param:[{}]"</span>,&#xA0;JSON.toJSONString(usernameAndPassword));<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>new</span>&#xA0;JwtToken(ljwtService.generateToken(<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;usernameAndPassword.getUsername(),<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;usernameAndPassword.getPassword()));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*&#x6CE8;&#x518C;&#x7528;&#x6237;&#x5E76;&#x4E14;&#x8FD4;&#x56DE;&#x6CE8;&#x518C;&#x5F53;&#x524D;&#x7528;&#x6237;&#x7684;token&#xA0;&#x5C31;&#x662F;&#x901A;&#x8FC7;&#x6388;&#x6743;&#x4E2D;&#x5FC3;&#x5E38;&#x89C1;&#x7528;&#x6237;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@IgnoreResponseAdvice</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@PostMapping</span>(<span>"/register"</span>)<br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;JwtToken&#xA0;<span>register</span><span>(@RequestBody&#xA0;UsernameAndPassword&#xA0;usernameAndPassword)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"register&#xA0;user&#xA0;with&#xA0;param:[{}]"</span>,&#xA0;JSON.toJSONString(usernameAndPassword));<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>new</span>&#xA0;JwtToken(ljwtService.registerUserAndGenerateToken(usernameAndPassword));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}

鉴权编码实现

这里我们打鉴权 放到公共模块里 为什么呢,这里我们不止是鉴权中心还有其他的服务也要用到鉴权服务,秉着封装的思想,我们提取公共的方法放到 Common里面

创建JWT Token解析类TokenParseUtil

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;JWT&#xA0;Token&#xA0;&#x89E3;&#x6790;&#x5DE5;&#x5177;&#x7C7B;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>public</span>&#xA0;<span><span>class</span>&#xA0;<span>TokenParseUtil</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>static</span>&#xA0;LoginUserinfo&#xA0;<span>parseUserInfoFromToken</span><span>(String&#xA0;token)</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>if</span>&#xA0;(<span>null</span>&#xA0;==&#xA0;token)&#xA0;{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>null</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;Jws<claims>&#xA0;claimsJws&#xA0;=&#xA0;parseToken(token,&#xA0;getPublicKey());<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;Claims&#xA0;body&#xA0;=&#xA0;claimsJws.getBody();<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x5982;&#x679C;&#xA0;Token&#xA0;&#x5DF2;&#x7ECF;&#x8FC7;&#x671F;&#x8FD4;&#x56DE;&#xA0;null</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>if</span>&#xA0;(body.getExpiration().before(Calendar.getInstance().getTime()))&#xA0;{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;<span>null</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;}<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#x8FD4;&#x56DE;&#xA0;Token&#x4E2D;&#x4FDD;&#x5B58;&#x7684;&#x7528;&#x6237;&#x4FE1;&#x606F;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;JSON.parseObject(<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;body.get(CommonCanstant.JWT_USER_INFO_KEY).toString(),&#xA0;LoginUserinfo<span>.<span>class</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;)</span>;<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x901A;&#x8FC7;&#x516C;&#x94A5;&#x53BB;&#x89E3;&#x6790;&#xA0;JWT&#xA0;Token<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>private</span>&#xA0;<span>static</span>&#xA0;Jws<claims>&#xA0;<span>parseToken</span><span>(String&#xA0;token,&#xA0;PublicKey&#xA0;publicKey)</span>&#xA0;</claims></span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#xA0;&#x7528;&#x8BBE;&#x7F6E;&#x7B7E;&#x540D;&#x516C;&#x94A5;&#xFF0C;&#x89E3;&#x6790;claims&#x4FE1;&#x606F;&#xA0;token</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>/*<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;&#x6839;&#x636E;&#x672C;&#x5730;&#x5B58;&#x50A8;&#x7684;&#x516C;&#x94A5;&#x83B7;&#x53D6;&#x5230;&#xA0;getPublicKey<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;*&#xA0;*/</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>static</span>&#xA0;PublicKey&#xA0;<span>getPublicKey</span><span>()</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x89E3;&#x7801;&#x5668;&#xA0;&#x6211;&#x4EEC;&#x8BBE;&#x7F6E;&#x89E3;&#x7801;&#x5668;&#xA0;&#x5C06;&#x516C;&#x94A5;&#x653E;&#x8FDB;&#x53BB;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;X509EncodedKeySpec&#xA0;keySpec&#xA0;=&#xA0;<span>new</span>&#xA0;X509EncodedKeySpec(<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>new</span>&#xA0;BASE64Decoder().decodeBuffer(CommonCanstant.PUBLIC_KEY)<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>//&#x521B;&#x5EFA;&#xA0;RSA&#xA0;&#x5B9E;&#x4F8B;&#xA0;&#x901A;&#x8FC7;&#x793A;&#x4F8B;&#x751F;&#x6210;&#x516C;&#x94A5;&#x5BF9;&#x8C61;</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>return</span>&#xA0;KeyFactory.getInstance(<span>"RSA"</span>).generatePublic(keySpec);<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}<br></claims>

这里是涉及到一个问题 ,token要是传输的不是jwt token对象,会跑出异常,没有兜底,

其实这里这问题其实也不成立,应为你没有传入token对象,我们这里抛出异常是正确的,也不会影响其他服务,之后搭配sentinel和豪猪哥 可以实现异常重启等等,这里我们就先不编写兜底方法,以解析jwt token为主。

验证鉴权授权

我们写一个 test 类来测试 授权和鉴权拿到对象,是否有效

<span>/**<br>&#xA0;*&#xA0;<span>@author</span>&#xA0;:&#xA0;&#x51B7;&#x73AF;&#x6E0A;<br>&#xA0;*&#xA0;<span>@date</span>&#xA0;:&#xA0;2021/12/5<br>&#xA0;*&#xA0;<span>@context</span>:&#xA0;JWT&#xA0;&#x76F8;&#x5173;&#x6D4B;&#x8BD5;&#x7C7B;<br>&#xA0;*&#xA0;<span>@params</span>&#xA0;:&#xA0;&#xA0;null<br>&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;&#xA0;*&#xA0;<span>@return</span>&#xA0;:&#xA0;null<br>&#xA0;*/</span><br><span>@Slf</span>4j<br><span>@SpringBootTest</span><br><span>@RunWith</span>(SpringRunner<span>.<span>class</span>)<br><span>public</span>&#xA0;<span>class</span>&#xA0;<span>JWTServiceTest</span>&#xA0;</span>{<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Autowired</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>private</span>&#xA0;IJWTService&#xA0;ijwtService;<br><br>&#xA0;&#xA0;&#xA0;&#xA0;<span>@Test</span><br>&#xA0;&#xA0;&#xA0;&#xA0;<span><span>public</span>&#xA0;<span>void</span>&#xA0;<span>testGenerateAndParseToken</span><span>()</span>&#xA0;<span>throws</span>&#xA0;Exception&#xA0;</span>{<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;String&#xA0;jwtToken&#xA0;=&#xA0;ijwtService.generateToken(<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;<span>"hyc@qq.com"</span>,&#xA0;<span>"e10adc3949ba59abbe56e057f20f883e"</span><br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"jwt&#xA0;token&#xA0;is:[{}]"</span>,&#xA0;jwtToken);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;LoginUserinfo&#xA0;userinfo&#xA0;=&#xA0;TokenParseUtil.parseUserInfoFromToken(jwtToken);<br>&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;&#xA0;log.info(<span>"userinfo&#xA0;by&#xA0;jwt&#xA0;prase&#xA0;token&#xA0;:[{}]"</span>,&#xA0;JSON.toJSONString(userinfo));<br>&#xA0;&#xA0;&#xA0;&#xA0;}<br>}

启动测试查看结果

eyJhbGciOiJSUzI1NiJ9<br><br>.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjExLFwidXNlcm5hbWVcIjpcImh5Y0BxcS5jb21cIn0iLCJqdGkiOiIzNDgwNjdjMi00MTBlLTQ3MjItYmM3ZS02NWQyYmNmYTRkN2MiLCJleHAiOjE2Mzg3MjAwMDB9<br><br>.ZbFl81MkIipJSULZLf4F2X2Fb0q1TwhHIMT7nyZsZVwUxXyZnK54RlzoGM_b-kMUdKO_Tab-qEeOT6Jn--FiKmbOziWXiBx3a-k5ipthMJx0Fez-X8Acty-Pg7zukNalugiLxGb5ophQoVQWRTDmv2hytGHqiV71HVyErznkJa36QQr6QsjXqlJleo3BBt-<span>6</span>BFzdTFPLUmdTEJ4XsmZBa_acUDGBhY0_tU2gYtKBWhwvMCknuyCcV-_GVI5EvgMIKRpeFSZrWfTsDG2y1MFcyzjKE6jnzek-YwT3XkzQ8eGzUbiOlaU_Zx5OJah-UtrKwqlAw9WbO71pNgEBefdsYw

这是封装好的 JWT Token 这里我们可以看到三个点分别分割 了 header和payload以及签名,和我们之前讲的 结构一模一样,

userinfo&#xA0;by&#xA0;jwt&#xA0;prase&#xA0;token&#xA0;:[{<span>"id"</span>:11,<span>"username"</span>:<span>"hyc@qq.com"</span>}]

获取到的我们放在jwt 里面需要传递的对象

验证对外提供的接口是否好用

这里我们编写 http脚本来测试对外题提供的接口是否有用

  • *Token 方法
<span>###&#xA0;&#x83B7;&#x53D6;&#xA0;Token&#xA0;--&#xA0;&#x767B;&#x5F55;&#x529F;&#x80FD;&#x5B9E;&#x73B0;</span><br>POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/token<br>Content-Type:&#xA0;application/json<br><br>{<br>&#xA0;&#xA0;<span>"username"</span>:&#xA0;<span>"hyc@qq.com"</span>,<br>&#xA0;&#xA0;<span>"password"</span>:&#xA0;<span>"e10adc3949ba59abbe56e057f20f883e"</span><br>}
POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/token<br><br>HTTP/1.1&#xA0;200&#xA0;<br>Content-Type:&#xA0;application/json<br>Transfer-Encoding:&#xA0;chunked<br>Date:&#xA0;Sun,&#xA0;05&#xA0;Dec&#xA0;2021&#xA0;15:35:52&#xA0;GMT<br>Keep-Alive:&#xA0;timeout=60<br>Connection:&#xA0;keep-alive<br><br>{<br>&#xA0;&#xA0;<span>"token"</span>:&#xA0;<span>"eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjExLFwidXNlcm5hbWVcIjpcImh5Y0BxcS5jb21cIn0iLCJqdGkiOiIxNDU1M2FjZi1lZmE5LTQ4OTgtOTliYS1hNzA4NWI4MjU4MzAiLCJleHAiOjE2Mzg3MjAwMDB9.AlOpo6uf97R20ZLojXeun-3MK8DpSYlWxEygvDrtQeWaM9R0iKx-iW1VXnK6WoEntvqPxIrmPA7khjl3dXPa8kQHtdq-LVO7BDuZZDiQyZ64ZS7A9jWZr5JReSWBUSR1YUnsOvBRMkx4JVcAF3_W7nHwd722FFzOZRCr72hLHQIKpsugKtqjMEtaiEW0vcqphCYRJTAO_rQx1Lb1eVVg_Ufur0qSlKkV5dSJ0x3x9mc9UZRckwN0rrP7wQxZcrxJvKTfX7CkRRSO-CxZbG4WLokSaMtaGBMWU-7KGq7HSCZ0yuOgbbLdouHncsp6VD2tNLFdWSdJ_whCIbZxfX8R7w"</span><br>}

获取 token 成功

这里他没有被响应包裹,证明我们之前的选择屏蔽注解也生效了,很符合我们的预期

  • *验证如果记录数据表没有是否会返回null
<span>###&#xA0;&#x83B7;&#x53D6;&#xA0;Token&#xA0;--&#xA0;&#x767B;&#x5F55;&#x529F;&#x80FD;&#x5B9E;&#x73B0;</span><br>POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/token<br>Content-Type:&#xA0;application/json<br><span>###&#xA0;&#x968F;&#x4FBF;&#x5199;&#x7684;id</span><br><br>{<br><span>"username"</span>:&#xA0;<span>"hyc1111@qq.com"</span>,<br><span>"password"</span>:&#xA0;<span>"e10adc3949ba59abbe56e057f20f883e"</span><br>}

返回结果 也符合我们预期 是 null

POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/token<br><br>HTTP/1.1&#xA0;200&#xA0;<br>Content-Type:&#xA0;application/json<br>Transfer-Encoding:&#xA0;chunked<br>Date:&#xA0;Sun,&#xA0;05&#xA0;Dec&#xA0;2021&#xA0;15:40:44&#xA0;GMT<br>Keep-Alive:&#xA0;timeout=60<br>Connection:&#xA0;keep-alive<br><br>{<br>&#xA0;&#xA0;<span>"token"</span>:&#xA0;null<br>}
  • *register
<span>###&#xA0;&#x6CE8;&#x518C;&#x7528;&#x6237;&#x5E76;&#x8FD4;&#x56DE;&#xA0;Token&#xA0;--&#xA0;&#x6CE8;&#x518C;&#x529F;&#x80FD;&#x5B9E;&#x73B0;</span><br>POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/register<br>Content-Type:&#xA0;application/json<br><br>{<br>&#xA0;&#xA0;<span>"username"</span>:&#xA0;<span>"hyc@qq.com"</span>,<br>&#xA0;&#xA0;<span>"password"</span>:&#xA0;<span>"e10adc3949ba59abbe56e057f20f883e"</span><br>}

这个用户之前是注册过的,我们来看一下是否会返回我们预期的处理

POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/register<br><br>HTTP/1.1&#xA0;200&#xA0;<br>Content-Type:&#xA0;application/json<br>Transfer-Encoding:&#xA0;chunked<br>Date:&#xA0;Sun,&#xA0;05&#xA0;Dec&#xA0;2021&#xA0;15:42:00&#xA0;GMT<br>Keep-Alive:&#xA0;timeout=60<br>Connection:&#xA0;keep-alive<br><br>{<br>&#xA0;&#xA0;<span>"token"</span>:&#xA0;null<br>}
  • *现在我们去注册一个新的用户
<span>###&#xA0;&#x6CE8;&#x518C;&#x7528;&#x6237;&#x5E76;&#x8FD4;&#x56DE;&#xA0;Token&#xA0;--&#xA0;&#x6CE8;&#x518C;&#x529F;&#x80FD;&#x5B9E;&#x73B0;</span><br>POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/register<br>Content-Type:&#xA0;application/json<br><br>{<br>&#xA0;&#xA0;<span>"username"</span>:&#xA0;<span>"hyc11@qq.com"</span>,<br>&#xA0;&#xA0;<span>"password"</span>:&#xA0;<span>"e10adc3949ba59abbe56e057f20f883e"</span><br>}

符合预期结果,创建了我们预期的对象,这个时候我们去看一下数据表

POST&#xA0;http://127.0.0.1:7000/ecommerce-authority-center/authority/register<br><br>HTTP/1.1&#xA0;200&#xA0;<br>Content-Type:&#xA0;application/json<br>Transfer-Encoding:&#xA0;chunked<br>Date:&#xA0;Sun,&#xA0;05&#xA0;Dec&#xA0;2021&#xA0;15:42:57&#xA0;GMT<br>Keep-Alive:&#xA0;timeout=60<br>Connection:&#xA0;keep-alive<br><br>{<br>&#xA0;&#xA0;<span>"token"</span>:&#xA0;<span>"eyJhbGciOiJSUzI1NiJ9.eyJlLWNvbW1lcmNlLXVzZXIiOiJ7XCJpZFwiOjEyLFwidXNlcm5hbWVcIjpcImh5YzExQHFxLmNvbVwifSIsImp0aSI6IjMxNDc0NmIwLTMyOGYtNDZkNS05ZTIwLTg3YjI0OWY1ZjZkOCIsImV4cCI6MTYzODcyMDAwMH0.MKxk-Q4BG5kaYFAsLiy13trtk_gDFmCKORpdE4EAwgSVecXFQcYfT1VvqSAKvoQLFsSlQAxOR5elV8CFOoKwAomwqdyyghZp63NKJ2smRbg3Y-4jWBzFVsUgcjOY2fwh7oNTdHEsWmLBYAh5r0hm_MysZsUEsE-cwb3sw8NSMk1OZp0J6tcRras7V1Uw5xXH8OnCoq2cUfdynJMHS29EzJT1TFPb8unVQ_A1RWodsHdK3n1Bl4wFbJjMtnHx7vzOeAUSNJx1XpAGdo0xYHK6HBpS9E1KBS3x1AnYFONM0DKd4-_QxMkBW1kkg2uWrRpf3GYZF20FKxXgmBAPHGZhew"</span><br>}

对象生成,功能验证一切正常

鉴权服务中心总结

对比基于Token与基于服务器的身份认证

传统:
  • 最为传统的做法,客户端储存 cookie 一般是 Session id 服务器存储 Session
  • Session 是每次用户认证通过以后 ,服务器需要创建一条记录保存用户信息,通常是在内存中(也可以放在redis中),随着认证通过的用户越来越多,服务器的在这里的开销就会越来越大
  • 不同域名之前切换的时候,请求可能会被禁止,即跨越问题

搭建SpringCloud Alibaba鉴权中心服务(详细教程)
基于token:
  • JWT与Session的差异相同点是,他们都是存储用户信息。然而Session是在服务器端的,而JWT是在客户端的
  • JWT方式将用户状态分散到了客户端中,可以明显减轻请服务器的内存压力,服务端只需要用算法解析客户端的token就可以得到信息

搭建SpringCloud Alibaba鉴权中心服务(详细教程)
  • 两者优缺点的对比
  • 解析方法:JWT使用算法直接解析得到用户信息;Session需要额外的数据映射。实现匹配
  • 管理方法:JWT只有过期时间的限制,Session 数据保存在服务器,可控性更强
  • 跨平台:JWT就是一段字符串,可以任意传播,Session跨平台需要有统一的解析平台,较为繁琐
  • 时效性:JWT一旦生成 独立存在,很难做到特殊的控制;Session时效性完全由服务端的逻辑说了算

TIPS :各自都有优缺点,都是登陆和授权的解决方案

来源:blog.csdn.net/doomwatcher/article/details/121743887

ps:如果您觉文章有用,动动小手点个在看,点个赞再走吧!

Original: https://www.cnblogs.com/konglxblog/p/16749347.html
Author: china_coding
Title: 搭建SpringCloud Alibaba鉴权中心服务(详细教程)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/570365/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 服务端高并发分布式架构演进之路

    1. 概述 本文以淘宝作为例子,介绍从一百个并发到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了…

    Java 2023年5月30日
    077
  • 00RocketMQ【目录】

    RocketMQ【目录】 posted on2022-06-11 18:17 格物致知_Tony 阅读(10 ) 评论() 编辑 Original: https://www.cnb…

    Java 2023年5月29日
    086
  • 从-99打造Sentinel高可用集群限流中间件

    接上篇Sentinel集群限流探索,上次简单提到了集群限流的原理,然后用官方给的 demo 简单修改了一下,可以正常运行生效。 这一次需要更进一步,基于 Sentinel 实现内嵌…

    Java 2023年6月13日
    060
  • [Java]HashMap与ConcurrentHashMap的一些总结

    HashMap底层数据结构 JDK7:数组+链表 JDK8:数组+链表+红黑树 JDK8中的HashMap什么时候将链表转为红黑树? 当发现链表中的元素大于8之后,判断当前数组长度…

    Java 2023年6月5日
    078
  • 几种流行的AJAX框架jQuery,Mootools,Dojo,Ext JS的对比

    AJAX是 web2.0的基石,现在网上流行几种开源的AJAX框架,比如:jQuery,Mootools,Dojo,Ext JS等等,那么我们到底在什么情况下该使用那个框架? 让我…

    Java 2023年6月9日
    090
  • IO(字符流的使用操作)

    OutputStreamWriter(使用)—写数据–(一次写入一个字符) OutputStreamWriter(OutputStream out):根据默…

    Java 2023年6月5日
    082
  • Redis篇:单线程I/O模型

    关注公众号,一起交流,微信搜一搜: 潜行前行 redis 单线程 I/O 多路复用模型 纯内存访问,所有数据都在内存中,所有的运算都是内存级别的运算,内存响应时间的时间为纳秒级别。…

    Java 2023年6月5日
    095
  • linux中find命令的摘要

    find命令的使用 按照时间查找 可以很方便按照时间查找文件 find -[mtime|atime|ctime] n #查找n天前当天[修改|访问|创建]的文件 find -[mt…

    Java 2023年6月7日
    089
  • Docker:Docker基础知识

    docker是什么 docker 是一个基于Go语言的开源应用容器引擎。 docker可以让开发者打包自己的应用到一个轻量级、可移植的容器中,实现容器化。 不同容器内的程序不会相互…

    Java 2023年6月7日
    066
  • MySQL、Oracle元数据抽取分析

    最近接到个任务是抽取mysql和Oracle的元数据,大致就是在库里把库、schema、表、字段、分区、索引、主键等信息抽取出来,然后导成excel。 因为刚开始接触元数据,对这个…

    Java 2023年6月5日
    086
  • Spark安装

    今天安装了spark posted @2022-09-21 16:48 山海自有归期 阅读(9 ) 评论() 编辑 Original: https://www.cnblogs.co…

    Java 2023年6月7日
    088
  • springboot 模拟上次文件: MultipartFile + json餐食

    首先来看,接口及参数 postman模拟上传 需求:将生成好的,远程excel附件,以及一些常规数据通过接口,传递过去。 代码部分: 1.将远程excel附件,转化为Multipa…

    Java 2023年5月30日
    088
  • 十大排序算法

    冒泡排序 从数组头开始,比较相邻的元素。如果第一个比第二个大(小),就交换它们两个 对每一对相邻元素作同样的工作,从开始第一对到尾部的最后一对,这样在最后的元素应该会是最大(小)的…

    Java 2023年6月5日
    0115
  • 日常踩坑_下载文件时文件名是乱码

    背景提要 一个下载文件的controller,下载下来内容虽然正常,但是文件名一直是乱码。 解决 需要清晰的一点就是,下载的文件名仅与请求头有关所以实际只要设置一下 respons…

    Java 2023年6月7日
    068
  • SpringCloudAlibaba项目之Nacos搭建及服务注册

    SpringCloudAlibaba随笔目录 一、SpringCloudAlibaba项目之父工程搭建 二、 SpringCloudAlibaba项目之Nacos搭建及服务注册 三…

    Java 2023年6月5日
    073
  • Nginx总结(九)Nginx服务器高性能优化的配置–轻松实现10万并发访问量

    前面讲了如何配置Nginx虚拟主机,如何配置服务日志等很多基础的内容,大家可以去这里看看nginx系列文章:https://www.cnblogs.com/zhangweizhon…

    Java 2023年5月30日
    065
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球