使用JWT认证遇Postman提示无效Base64字符串问题排查
问题:JWT身份认证时出现Base64编码无效的500错误
在学校项目中尝试用JWT令牌实现身份认证,当令牌包含role="coach"声明时用户拥有对应操作权限。编写的JWT生成与解析方法能在jwt.io正常解析令牌,但在Postman中传入令牌调用接口时,返回500内部服务器错误,提示“输入不是有效的Base64编码字符串”。使用Auth0库4.2.1版本。
相关代码
JWT生成与验证方法
Algorithm algorithm = Algorithm.HMAC256("wisebite"); public String login() { String jwtToken = JWT.create() .withIssuer("wisebite") .withSubject("wisebitedetails") .withClaim("role", "coach") .withIssuedAt(new Date()) .withExpiresAt(new Date(System.currentTimeMillis() + 5000L)) .withJWTId(UUID.randomUUID() .toString()) .withNotBefore(new Date(System.currentTimeMillis() + 1000L)) .sign(algorithm); return jwtToken; } public boolean hasAcces (String jwtToken) { JWTVerifier jwtVerifier = JWT.require(algorithm).withIssuer("wisebite").build(); DecodedJWT decodedJWT = jwtVerifier.verify(jwtToken); if (decodedJWT.getClaim("role").equals("coach")) { return true; } else { return false; } }
获取到的令牌
调用http://localhost:8080/coach/login接口得到的令牌:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3aXNlYml0ZWRldGFpbHMiLCJyb2xlIjoiY29hY2giLCJuYmYiOjE3MDk3MTM3ODQsImlzcyI6Indpc2ViaXRlIiwiZXhwIjoxNzA5NzEzNzg4LCJpYXQiOjE3MDk3MTM3ODMsImp0aSI6ImY4Zjc3NzkxLTlmYjgtNDNlNi1iNTFjLTRlOTk1ZDQ2NGZmYyJ9.8sitspmE0N_Ai47qrIQmrp4szVc4mwDANlpN5L0jJbg
触发错误的接口代码
@GetMapping("/overview/{username}") private ResponseEntity<PlanDTO> getPlanByClient(@PathVariable String username, @RequestBody String jwtToken) { if (authenticationService.hasAcces(jwtToken)) { // 后续业务逻辑 } }
问题原因及解决办法
GET请求不支持RequestBody
你用@GetMapping定义接口,却通过@RequestBody接收JWT令牌。HTTP规范中GET请求没有请求体,Postman发送带请求体的GET请求时,服务器解析会出现异常,导致令牌格式被破坏,触发Base64无效的错误。JWT验证逻辑错误
decodedJWT.getClaim("role")返回的是Claim对象,直接用equals("coach")比较的是对象引用,永远不会相等。需要用asString()方法将Claim转为字符串后再比较:if ("coach".equals(decodedJWT.getClaim("role").asString())) { return true; }JWT传递方式不符合规范
JWT令牌应放在HTTP请求的Authorization头中,格式为Bearer <令牌>,而非请求体。修改接口代码如下:@GetMapping("/overview/{username}") private ResponseEntity<PlanDTO> getPlanByClient(@PathVariable String username, @RequestHeader("Authorization") String authHeader) { // 提取Bearer前缀后的令牌内容 String jwtToken = authHeader.replace("Bearer ", ""); if (authenticationService.hasAcces(jwtToken)) { // 后续业务逻辑 } }
内容的提问来源于stack exchange,提问作者Mark Fijn
相关产品推荐
相关产品推荐

