Skip to content

Commit 2425be3

Browse files
update
1 parent 0925bcd commit 2425be3

27 files changed

Lines changed: 1272 additions & 626 deletions

File tree

24.6 KB
Loading
48.9 KB
Loading
63.9 KB
Loading

notes/微服务/微服务.md

Lines changed: 254 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -826,51 +826,301 @@ public class JWTClient {
826826
System.out.println("payload:"+claims.getIssuedAt());
827827
System.out.println("payload:"+claims.getExpiration());
828828
System.out.println("payload:"+claims.getAudience());
829-
830829
System.out.println("signature:"+jws.getSignature());
830+
System.out.println(jws.getSignature().equals(token.split("\\.")[2]));
831+
}
832+
833+
public static void main(String[] args) {
834+
visitServer();
835+
}
836+
837+
}
831838

839+
```
832840

841+
Spring Boot整合jwt
833842

834-
System.out.println(jws.getSignature().equals(token.split("\\.")[2]));
843+
为了让所有的功能模块 都能拥有 分布式校验功能(jwt),需要将这个校验功能 放到通用模块中。micro_commom:
844+
845+
1.引入jwt依赖
846+
847+
```xml
848+
<dependency>
849+
<groupId>io.jsonwebtoken</groupId>
850+
<artifactId>jjwt</artifactId>
851+
<version>0.9.1</version>
852+
</dependency>
853+
854+
<dependency>
855+
<groupId>org.springframework.boot</groupId>
856+
<artifactId>spring-boot-configuration-processor</artifactId>
857+
<optional>true</optional>
858+
</dependency>
859+
```
860+
861+
2.配置
862+
863+
```xml
864+
省略
865+
```
866+
867+
868+
869+
3.编码
870+
871+
```java
872+
package util;
873+
874+
import io.jsonwebtoken.Claims;
875+
import io.jsonwebtoken.Jwts;
876+
import io.jsonwebtoken.SignatureAlgorithm;
877+
import org.springframework.boot.context.properties.ConfigurationProperties;
878+
879+
import java.util.Date;
835880

881+
/*
882+
* Created by 颜群
883+
*/
884+
@ConfigurationProperties("jwt.config")
885+
public class JwtUtil {
886+
private String key ;
887+
private long ttl ;
836888

889+
public String getKey() {
890+
return key;
891+
}
837892

893+
public void setKey(String key) {
894+
this.key = key;
895+
}
838896

897+
public long getTtl() {
898+
return ttl;
839899
}
840900

841-
public static void main(String[] args) {
842-
visitServer();
901+
public void setTtl(long ttl) {
902+
this.ttl = ttl;
903+
}
904+
905+
//服务端生成jwt-token的方法 (JWTServer)
906+
public String createJWT(String id, String subject,String roles){
907+
Date now = new Date() ;
908+
long nowMillis = System.currentTimeMillis() ;
909+
910+
return Jwts.builder().setId(id)
911+
.setSubject(subject)
912+
.setIssuedAt( now )
913+
.setExpiration( new Date( nowMillis + ttl ) )
914+
.signWith( SignatureAlgorithm.HS256, key )
915+
.claim("roles",roles).compact() ;//token
843916
}
844917

918+
919+
//客户单发送jwt-token时进行的校验方法 (JWTClient)
920+
public Claims parseJWT(String token){
921+
return Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody() ;
922+
}
845923
}
846924

925+
847926
```
848927

849928

850929

930+
微服务的校验逻辑:第一登录时 获取token;以后再操作时,需要拿着token去访问。
851931

932+
![1594024091872](微服务.assets/1594024091872.png)
852933

853934

854935

855936

856937

938+
登录工程:
857939

940+
micro_people
858941

942+
PeopleController.java
859943

944+
```java
945+
//用户名:username
946+
//密码:password
947+
@PostMapping(value="/login")
948+
public Message login(@RequestBody Map<String,String> login){
949+
//controller -sercice -dao 模拟操作
950+
String uname = login.get("username") ;
951+
String upwd = login.get("password") ;
952+
//findUserByUsernameAndPassword
953+
//zs/abc -> 返回这个人的全部信息 User(zs/abc,id(1001).....)
954+
955+
System.out.println("1111");
956+
//假设数据库中的zs/abc (并且:假设这个人的id1001,这个人是管理员权限admin )
957+
if(uname.equals("zs") && upwd.equals("abc")){
958+
//登录成功,服务端生成token
959+
//String id, String subject,String roles
960+
String token = jwtUtil.createJWT("1001", "zs", "admin");
961+
962+
Map map = new HashMap() ;
963+
map.put("token",token) ;
964+
map.put("username",uname) ;
965+
966+
System.out.println("登录成功");
967+
//登录成功:返回token\用户名
968+
return new Message(true,StatusCode.OK,map) ;
969+
}else{
970+
System.out.println("登录失败");
971+
return new Message(false,StatusCode.ERROR) ;
972+
}
860973

861974

975+
}
976+
```
977+
978+
xml
979+
980+
```
981+
jwt: config:
982+
key: yanqun
983+
ttl: 1800
984+
```
985+
986+
![1594027935455](微服务.assets/1594027935455.png)
987+
988+
989+
990+
sb方式的解析:
991+
992+
客户端校验token - 服务端token
993+
994+
客户端如何 携带 token去校验? 自定义请求头 Header
862995

996+
key-value
863997

998+
key: authentication
864999

1000+
value: yanqun-token
8651001

1002+
在需要校验的操作上,增加jwt解析:
1003+
1004+
```java
1005+
1006+
@DeleteMapping("deleteById/{id}")
1007+
public Message deleteById( @PathVariable("id") Integer id){
1008+
1009+
//删除之前 先通过jwt进行权限校验
1010+
/*
1011+
已经存在生成jwt
1012+
1013+
现在:解析jwt
1014+
1.客户端将jwt 传递给服务端 (postman模拟)
1015+
2.解析jwt
1016+
*/
1017+
//假设此时,客户端postman已经将jwt(token)传递过来了
1018+
String authentication = request.getHeader("authentication");
1019+
if(authentication == null) {//请求时(postman)时,并没有携带jwt
1020+
return new Message(false,StatusCode.ERROR,"权限不足!") ;
1021+
}
1022+
1023+
String token = authentication.substring(7);//从yanqun-token截取出token
1024+
Claims claims = jwtUtil.parseJWT(token);
1025+
String roles = (String)claims.get("roles");
1026+
System.out.println(roles+"roles");
1027+
if(!roles.equals("admin")){
1028+
return new Message(false,StatusCode.ERROR,"权限不足!") ;
1029+
}
1030+
1031+
1032+
boolean result =cityService.deleteById(id) ;
1033+
return new Message(true, StatusCode.OK, result );
1034+
}
1035+
```
1036+
1037+
![1595211856571](微服务.assets/1595211856571.png)
8661038

8671039

8681040

1041+
为了减少代码的冗余量,建议 将解析操作 放到拦截器中。一个微服务,一个拦截器。
8691042

1043+
定义拦截器
8701044

1045+
```java
1046+
package com.yanqun.micro_city.interceptor;
1047+
1048+
import io.jsonwebtoken.Claims;
1049+
import org.springframework.beans.factory.annotation.Autowired;
1050+
import org.springframework.stereotype.Component;
1051+
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
1052+
import util.JwtUtil;
8711053

1054+
import javax.servlet.http.HttpServletRequest;
1055+
import javax.servlet.http.HttpServletResponse;
8721056

1057+
/*
1058+
* Created by 颜群
1059+
*/
1060+
@Component
1061+
public class JwtInterceptor extends HandlerInterceptorAdapter {
8731062

8741063

1064+
//请求 ->拦截器(pre) -> 增删改
1065+
@Autowired
1066+
private JwtUtil jwtUtil ;
8751067

1068+
@Autowired
1069+
private HttpServletRequest request ;
1070+
1071+
1072+
1073+
@Override
1074+
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
1075+
System.out.println("jwt拦截器...");
1076+
String authentication = request.getHeader("authentication");
1077+
if(authentication != null && authentication.startsWith("yanqun-")) {
1078+
String token = authentication.substring(7);
1079+
Claims claims = jwtUtil.parseJWT(token);
1080+
String roles = (String)claims.get("roles");
1081+
if(roles.equals("admin")){
1082+
request.setAttribute("claims",claims);
1083+
}
1084+
}
1085+
return true;
1086+
}
1087+
}
1088+
1089+
```
1090+
1091+
配置拦截器规则
1092+
1093+
```java
1094+
@Configuration
1095+
public class JwtConfig extends WebMvcConfigurationSupport {
1096+
1097+
@Autowired
1098+
private JwtInterceptor jwtInterceptor;
1099+
1100+
@Override
1101+
protected void addInterceptors(InterceptorRegistry registry) {
1102+
registry.addInterceptor(jwtInterceptor)
1103+
.addPathPatterns("/**")
1104+
.excludePathPatterns("/**/login"); //假设city项目中的登录映射叫 login,则排除登录
1105+
}
1106+
}
1107+
1108+
```
1109+
1110+
使用拦截器
1111+
1112+
```java
1113+
@DeleteMapping("deleteById/{id}")
1114+
public Message deleteById( @PathVariable("id") Integer id){
1115+
//如果拦截器 判断权限足够,则会在request中 放入一个claims参数;否则,没有claims参数
1116+
Claims claims = (Claims)request.getAttribute("claims");
1117+
if(claims == null){
1118+
return new Message(false,StatusCode.ERROR,"权限不足") ;
1119+
}
1120+
1121+
boolean result =cityService.deleteById(id) ;
1122+
return new Message(true, StatusCode.OK, result );
1123+
}
1124+
1125+
```
8761126

sources/microservice/.idea/compiler.xml

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)