Bootstrap

Spring Boot 项目集成Jwt.jsonwebtoken.MalformedJwtException: Unable to read JSON value: �z��&�r#�$�3S“

使用Spring Boot 集成Jwt令牌的时候出现了一个问题

首先报错的信息如下:

io.jsonwebtoken.MalformedJwtException: Unable to read JSON value: �z��&�r#�$�3S"
	at io.jsonwebtoken.impl.DefaultJwtParser.readValue(DefaultJwtParser.java:554)
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:252)
	at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:481)
	at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:541)
	at com.an.server.config.security.component.JwtTokenUtil.getClaimsFromToken(JwtTokenUtil.java:132)
	at com.an.server.config.security.component.JwtTokenUtil.getUsernameFromToken(JwtTokenUtil.java:51)
	at com.an.server.config.WebSocketConfig$1.preSend(WebSocketConfig.java:73)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: com.fasterxml.jackson.core.JsonParseException: Illegal character ((CTRL-CHAR, code 5)): only regular white space (\r, \n, \t) is allowed between tokens
 at [Source: (String)"�z��&�r#�$�3S""; line: 1, column: 2]
	at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:1851)
	at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:707)
	at com.fasterxml.jackson.core.base.ParserMinimalBase._throwInvalidSpace(ParserMinimalBase.java:685)
	at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._skipWSOrEnd(ReaderBasedJsonParser.java:2397)
	... 40 more

中间没用的代码我就直接省略了

错误原因:

我查了一下发现io.jsonwebtoken.MalformedJwtException 这个异常是来自JWT令牌校验的一个异常,说明JWT校验没有通过,一般出现这个问题可能有两种情况,

  • 一种是前端在传递token的时候与后端规定的 token 格式不一样
例如:后端要求的格式是
Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImNyZWF0ZWQiOjE2NDY4OTAxOTAwNjEsImV4cCI6MTY0NzQ5NDk5MH0.lBdHE2iG6qLqYeKRTUokTh4_NJPBTWsEkJd1JMkO9zx2bWsIG9YojCJtcL-jSC3rKgkPX6m9a2tvCXNfxdZfOw

而前端传递的token
eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJhZG1pbiIsImNyZWF0ZWQiOjE2NDY4OTAxOTAwNjEsImV4cCI6MTY0NzQ5NDk5MH0.lBdHE2iG6qLqYeKRTUokTh4_NJPBTWsEkJd1JMkO9zx2bWsIG9YojCJtcL-jSC3rKgkPX6m9a2tvCXNfxdZfOw

这种问题建议前端进行console.log() 去看看,格式是否有问题,或者是参数名

  • 另一种是后端在解析的时候没有处理好
例如:如果后端要求了 前缀 Bearer 
那么就要在后端获取的时候,先去截取掉前缀
然后再进行校验
否则就会出现如上的错误
建议在调用jwtUtils进行校验之前先打印一下token,看是不是自己当初要求的格式

我是属于前后端分离开发的,那么这个问题,在最后定位发现是后端的问题,因为后端中集成websocket的时候Jwt是拎出来单独配置的,因此websocket的Jwt校验配置是独立于其他接口的,我在进行token处理的时候少写了一步
别的接口打印:
在这里插入图片描述
在这里插入图片描述
如果问题和我类似,就去找对应的jwt校验配置吧

我最后的问题是忘记截取token头 Bearer
添加如下代码:

// 判断是否为连接,如果是需要获取token,并且设置用户对象
                if (StompCommand.CONNECT.equals(accessor.getCommand())) {
                    // 获取前端传递的token
                    String token = accessor.getFirstNativeHeader("Auth-Token");
                    // 判断token是否存在
                    if (!StringUtils.isEmpty(token)) {
                        // 截取 token字符串 (添加如下的代码 tokenHead是自己设置好的token头)
                        String authToken = token.substring(tokenHead.length());
                        String username = jwtTokenUtil.getUsernameFromToken(authToken);
                        // token中存在用户名
                        if (!StringUtils.isEmpty(username)) {
                            // 登录
                            UserDetails userDetails = userDetailsService.loadUserByUsername(username);
                            // 验证token是否有效
                            if (jwtTokenUtil.validateToken(authToken, userDetails)) {
                                UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities());
                                SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                                accessor.setUser(authenticationToken);
                            }
                        }
                    }
                }

最后测试通信成功

干完了 收工!!!!!

;