尝试解码 JWT 令牌以从令牌中提取信息时出现错误 喜欢
非法的base64url字符:''
这是我的服务类,当尝试执行声明时没有输出并抛出错误
我正在尝试验证用户是否在登录时生成了 jwt 令牌,当我尝试使用需要验证用户的不同服务时,我想从 JWT 令牌中提取用户信息并将其与数据库进行匹配
package com.example.RentCar.Services;
import java.security.Key;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import com.example.RentCar.DTOS.UserRequestDTO;
import com.example.RentCar.Models.User;
import com.example.RentCar.Repository.UserRepository;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.io.Decoders;
import io.jsonwebtoken.security.Keys;
@Service
public class JwtServicesImpl implements JwtServices {
private UserRequestDTO userRequestDTO;
//private final UserRepository userRepository;
// @Value("${token.signing.key}")
private String jwtSigningKey = "413F4428472B4B6250655368566D5970337336763979244226452948404D6351";
@Override
public String extractUserName(String token) {
return extractClaim(token, Claims::getSubject);
}
@Override
public String generateToken(User user) {
return generateToken(new HashMap<>(), user);
}
@Override
public boolean isTokenValid(String token, UserServicesImpl userServices) {
final String email = extractUserName(token);
UserDetails user = (userServices.loadUserByUsername(email));
String email2 = user.getUsername();
return (email.equals(email2) && !isTokenExpired(token));
}
private <T> T extractClaim(String token, Function<Claims, T> claimsResolvers) {
final Claims claims = extractAllClaims(token);
System.out.println(claims); //not printing
return claimsResolvers.apply(claims);
}
private String generateToken(Map<String, Object> extraClaims, User user) {
return Jwts.builder().setClaims(extraClaims).setSubject(user.getUserEmail())
.setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 24))
.signWith(getSigningKey(), SignatureAlgorithm.HS256).compact();
}
private boolean isTokenExpired(String token) {
return extractExpiration(token).before(new Date());
}
private Date extractExpiration(String token) {
return extractClaim(token, Claims::getExpiration);
}
private Claims extractAllClaims(String token) {
return Jwts.parserBuilder().setSigningKey(getSigningKey()).build().parseClaimsJws(token)
.getBody();
}
private Key getSigningKey() {
// System.out.println(jwtSigningKey);
byte[] keyBytes = Decoders.BASE64.decode(jwtSigningKey);
return Keys.hmacShaKeyFor(keyBytes);
}
}
```
below is the error
io.jsonwebtoken.io.DecodingException: Illegal base64url character: ' '
at io.jsonwebtoken.io.Base64.ctoi(Base64.java:221)
at io.jsonwebtoken.io.Base64.decodeFast(Base64.java:270)
at io.jsonwebtoken.io.Base64Decoder.decode(Base64Decoder.java:36)
at io.jsonwebtoken.io.Base64Decoder.decode(Base64Decoder.java:23)
at io.jsonwebtoken.io.ExceptionPropagatingDecoder.decode(ExceptionPropagatingDecoder.java:36)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:288)
at io.jsonwebtoken.impl.DefaultJwtParser.parse(DefaultJwtParser.java:529)
at io.jsonwebtoken.impl.DefaultJwtParser.parseClaimsJws(DefaultJwtParser.java:589)
at io.jsonwebtoken.impl.ImmutableJwtParser.parseClaimsJws(ImmutableJwtParser.java:173)
at com.example.RentCar.Services.JwtServicesImpl.extractAllClaims(JwtServicesImpl.java:76)
at com.example.RentCar.Services.JwtServicesImpl.extractClaim(JwtServicesImpl.java:55)
at com.example.RentCar.Services.JwtServicesImpl.extractUserName(JwtServicesImpl.java:34)
at com.example.RentCar.Controllers.UserController.ModifyAddress(UserController.java:36)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:578)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
Expecting should be like can claims or extract information from token
正如 Jon Skeet 所说,你的 jwtSigningKey 以十六进制编码,在 getSigningKey() 中,你告诉 Java 用 Base64 对其进行解码。
使用 Base64 编码密钥或使用 Hex 解码。