title: How can I refresh tokens in Spring security
body: <p>This line:</p>
  <pre><code>Jwts.parser().setSigningKey(SECRET_KEY).parseClaimsJws(token).getBody();
  </code></pre>
  <p>Throws an error like this when my jwt token expires:</p>
  <blockquote>
  <p>JWT expired at 2020-05-13T07:50:39Z. Current time:
  2020-05-16T21:29:41Z.</p>
  </blockquote>
  <p>More specifically, it is this function that throws the &quot;ExpiredJwtException&quot; exception :
  <a href="https://i.stack.imgur.com/D4tGl.png" rel="noreferrer"><img src="https://i.stack.imgur.com/D4tGl.png" alt="parseClaimsJws() function" /></a></p>
  <p>How do I go about handling these exceptions? Should I catch them and send back to the client an error message and force them to re-login?</p>
  <p>How can I implement a refresh tokens feature? I'm using Spring and mysql in the backend and vuejs in the front end.</p>
  <p>I generate the initial token like this:</p>
  <pre><code>   @Override
          public JSONObject login(AuthenticationRequest authreq) {
              JSONObject json = new JSONObject();
      
              try {
                  Authentication authentication = authenticationManager.authenticate(
                          new UsernamePasswordAuthenticationToken(authreq.getUsername(), authreq.getPassword()));
      
                  UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
                  List&lt;String&gt; roles = userDetails.getAuthorities().stream().map(item -&gt; item.getAuthority())
                          .collect(Collectors.toList());
      
                  if (userDetails != null) {
      
                      final String jwt = jwtTokenUtil.generateToken(userDetails);
      
      
                      JwtResponse jwtres = new JwtResponse(jwt, userDetails.getId(), userDetails.getUsername(),
                              userDetails.getEmail(), roles, jwtTokenUtil.extractExpiration(jwt).toString());
      
                      return json.put(&quot;jwtresponse&quot;, jwtres);
                  }
              } catch (BadCredentialsException ex) {
                  json.put(&quot;status&quot;, &quot;badcredentials&quot;);
              } catch (LockedException ex) {
                  json.put(&quot;status&quot;, &quot;LockedException&quot;);
              } catch (DisabledException ex) {
                  json.put(&quot;status&quot;, &quot;DisabledException&quot;);
              }
      
              return json;
          }
  </code></pre>
  <p>And then in the JwtUtil class:</p>
  <pre><code>   public String generateToken(UserDetails userDetails) {
              Map&lt;String, Object&gt; claims = new HashMap&lt;&gt;();
              return createToken(claims, userDetails.getUsername());
          }
      
     private String createToken(Map&lt;String, Object&gt; claims, String subject) {
              return Jwts.builder().setClaims(claims).setSubject(subject).setIssuedAt(new Date(System.currentTimeMillis()))
                      .setExpiration(new Date(System.currentTimeMillis() + EXPIRESIN))
                      .signWith(SignatureAlgorithm.HS256, SECRET_KEY).compact();
          }
  </code></pre>
  <p>For more info, here is my doFilterInternal function that filters every request:</p>
  <pre><code>   @Override
      protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
              throws ServletException, IOException, ExpiredJwtException, MalformedJwtException {
  
          try {
  
              final String authorizationHeader = request.getHeader(&quot;Authorization&quot;);
  
              String username = null;
              String jwt = null;
  
              if (authorizationHeader != null &amp;&amp; authorizationHeader.startsWith(&quot;Bearer &quot;)) {
                  jwt = authorizationHeader.substring(7);
                  username = jwtUtil.extractUsername(jwt);
              }
  
              if (username != null &amp;&amp; SecurityContextHolder.getContext().getAuthentication() == null) {
                  UserDetails userDetails = userService.loadUserByUsername(username);
  
                  boolean correct = jwtUtil.validateToken(jwt, userDetails);
  
                  if (correct) {
                      UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
                              userDetails, null, userDetails.getAuthorities());
  
                      usernamePasswordAuthenticationToken
                              .setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
                      SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
  
                  }
              }
  
              chain.doFilter(request, response);
          } catch (ExpiredJwtException ex) {
              resolver.resolveException(request, response, null, ex);
          }
      } 
  </code></pre>