java - 如何从 JWT 获取用户名?
问题描述
我有 2 个微服务。向客户发送消息的 API 网关和微服务。我的 API 在身份验证后返回一个 JWT 令牌。用户的用户名包含在令牌中。
public String extractUsername(String token)
{
return extractClaim(token, Claims::getSubject);
}
public Date extractExpiration(String token)
{
return extractClaim(token, Claims::getExpiration);
}
public <T> T extractClaim(String token, Function<Claims,T> claimsResolver)
{
final Claims claims = extractAllClaims(token);
return claimsResolver.apply(claims);
}
private Claims extractAllClaims(String token)
{
return Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
}
private Boolean isTokenExpired(String token)
{
return extractExpiration(token).before(new Date());
}
public String generateToken(UserDetails userDetails)
{
Map<String,Object> claims =new HashMap<>();
return createToken(claims,userDetails.getUsername());
}
private String createToken(Map<String, Object> claims, String subject)
{
return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
.setExpiration(new Date(System.currentTimeMillis() + 1000*60*60*24*360))
.signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
}
public Boolean validateToken(String token, UserDetails userDetails)
{
final String username = extractUsername(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
如果我想通过 API 网关寻址我的 SendMessage 微服务,他需要用户名来发送消息。我目前正在通过 Rest-Api 传递用户名。我希望 SendMessage 微服务从令牌中获取用户名。我读过这适用于 TokenEnhancer。但我没有找到更多信息。有人可以告诉我该怎么做或在哪里可以找到更多信息吗?
更新
@GetMapping("/contacts/sms/{name}/{customer_phone_number}/{text}")
public String sendSmsToCustomer(@PathVariable("name") String name,@PathVariable("customer_phone_number") String customer_phone_number, @PathVariable("text") String text) throws Exception
{
String user= getUsernameFromToken(HttpServletRequest request);
SmsSubmissionResponse responses = client.getSmsClient().submitMessage(new TextMessage(
name,
customer_phone_number,
text));
for (SmsSubmissionResponseMessage response : responses.getMessages()) {
System.out.println (response);
}
if (responses.getMessages().get(0).getStatus() == MessageStatus.OK) {
String date=new SimpleDateFormat("yyyy.MM.dd - HH:mm:ss").format(new java.util.Date());
SQL_Connection.SaveDataInSmsDB(name, customer_phone_number, text,date);
return "Message sent successfully.";
} else {
return "Message failed with error: " + responses.getMessages().get(0).getErrorText();
}
}
更新 2
@GetMapping("/contacts/sms/{name}/{customer_phone_number}/{text}")
public String sendSmsToCustomer(@RequestHeader(HEADER_STRING) HttpServletRequest request, @PathVariable("name") String name,@PathVariable("customer_phone_number") String customer_phone_number, @PathVariable("text") String text) throws Exception
{
String user= getUsernameFromToken(request);
System.out.println(user);
{
"timestamp": "2020-07-07T08:08:34.975+0000",
"status": 400,
"error": "Bad Request",
"message": "Missing request header 'Authorization' for method parameter of type HttpServletRequest",
"path": "/contacts/sms/segos/44256674/hallo%20Container%20kommt"
}
解决方案
您可以使用以下代码从 Token 中提取用户
String token = request.getHeader(HEADER_STRING);
String user = null;
if (token != null) {
// parse the token.
try {
user = Jwts.parser()
.setSigningKey(SECRET)
.parseClaimsJws(token.replace(TOKEN_PREFIX, ""))
.getBody()
.getSubject();
} catch (Exception e) {
throw e;
}
您可以参考完整的代码和项目
推荐阅读
- spring - 此应用程序没有 /error 的显式映射,
- java - 在sql spring boot中自动执行查询
- reactjs - 在 React 中通过 onChange 发送照片到银行?
- python - MS Word Scraping 适用于 docx 但不适用于 doc 文件
- wordpress - 按条件更改 wordpress gutenburg 块中返回部分中的标签
- python - 如何在 Mac 上使用键盘模块
- tensorflow - ResourceApplyGradientDescent 和 ApplyGradientDescent 有什么区别?
- excel - PLSQL 包,可在内部创建带有多页表的简单 excel 文件,并作为附件直接发送到电子邮件,无需使用 UTL
- python - 在字典中分隔空格 [Python]
- docker-compose - docker-compose 仍然使用带有 -f 选项的覆盖文件