2017-08-31 75 views
1

我在我的Web应用程序中成功实现了JWT作为认证过滤器。当用户的login成功时,我将创建一个新的JWT并在字段JWT中指定userName。 在随后的请求中,我在JWTsub字段中使用userName来标识用户。但是如果用户在应用程序的更新部分中更改他的userName会怎么样。有没有办法,我可以在JWT更新sub字段的值?动态更改JWT主题字段

我在想什么!

我想凑了RestController现有JWT的和更新后userName,我将与新userName更新JWT,再发回给客户端。这很好还是有更好的方法?

回答

1

我想我应该在更新完成后刷新令牌并将刷新的令牌发送回客户端。

@RequestMapping(value = "/account", method = RequestMethod.POST) 
public ResponseEntity<?> updateAccount(@RequestBody UserDetailsBean userDetailsBean, HttpServletRequest request, 
     HttpServletResponse response) 
{ 
    try 
    { 
     UserAccessDetails accessDetails = getLoggedInUser(); 
     UserDetailsBean updatedUserBean = userService.updateAccount(userDetailsBean, accessDetails); 

     // send updated jwt incase of mobile number update by user 
     response.addHeader(SecurityConstants.HEADER_STRING, 
       SecurityConstants.TOKEN_PREFIX + refreshJWT(updatedUserBean.getMobileNumber())); 
     return buildResponse(updatedUserBean); 
    } 
    catch(DataException e) 
    { 
     return buildError(e); 
    } 
} 

private String refreshJWT(String subject) 
{ 
    return Jwts.builder().setSubject((subject)) 
      .setExpiration(new Date(System.currentTimeMillis() + EXPIRATION_TIME)) 
      .signWith(SignatureAlgorithm.HS512, SecurityConstants.SECRET).compact(); 
} 

这是行得通的。如果有人有清洁和行业标准的方法,请注明。

1

如果您允许您的用户更改他们的用户名,他们还应该有一个不可变的用户ID,可用于识别与给定用户关联的任何数据或活动。否则,用户每次更改其名称时,都将失去审计用户过去操作的能力,或者必须更新数据库中该用户名的所有引用。更糟的是,如果在数据库中引用了旧用户名,而另一个用户使用该用户名 - 现在由于用户标识的处理不正确,您现在将一个用户的数据与另一个用户相关联。

现在说,子声明应该包含这个不可变的用户ID。您可以为可变用户名创建单独的声明。当用户名被改变时,你现在只需要改变数据库中的一个字段(假设只有users表引用了这个可变用户名)。然后,您可以使用刷新标记检索新的标记,该标记将包含最新的用户名,然后可以根据需要使用您的API。

使用这种方法,你应该小心仅使用用户名要求为显示目的,不用于识别由于它是可变的登录的用户。包含用户标识的子索赔将用于识别用户。

同样重要的是要注意,此解决方案要求任何特殊逻辑“更新子要求。”您将使用您已用于为提供的刷新令牌生成令牌的相同逻辑。

+0

现在,每当用户更新我创建一个新的'JWT'任何字段,它包含最新的'userName'在其可变'sub'场。 –