简体   繁体   中英

How JSON web token works in Spring boot?

I want to write REST service and I choose JWT for securing this rest service.
I declare 1 min for token, afterwards what I must do?
I must refresh token or something else?

If I must refresh token, user can call service's method with this token?

Token code

package com.example.demo.config;

import java.util.Date;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import java.util.ArrayList;
import java.util.Arrays;

public class TokenAuthenticationService {

    //field of conf
    static final long EXPIRATIONTIME = 60_000; // 1 min
    static final String SECRET = "msg";
    static final String TOKEN_PREFIX = "Bearer";
    static final String HEADER_STRING = "Authorization";

    //generate token
    public static void addAuthentication(HttpServletResponse res, Authentication auth) {
        String concattedRoles = "";
        for (GrantedAuthority ga : auth.getAuthorities()) {
            if (!"".equals(concattedRoles))
                 concattedRoles += "," + ga.getAuthority();
             else
                 concattedRoles += ga.getAuthority();
        }
        String JWT = Jwts.builder().setSubject(auth.getName()).claim("roles", concattedRoles)
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                .signWith(SignatureAlgorithm.HS512, SECRET).compact();
        res.addHeader(HEADER_STRING, TOKEN_PREFIX + " " + JWT);
    }

    //get token from request header.
    public static Authentication getAuthentication(HttpServletRequest request) {
        try {
            System.out.println("(Authentication getAuthentication(HttpServletRequest request)");
            String token = request.getHeader(HEADER_STRING);
            System.out.println("token=>"+token);
            if (token != null) {
                Claims claims = Jwts.parser().setSigningKey(SECRET).parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
                String user = claims.getSubject();
                String roles = (String) claims.get("roles");

                if(claims.getExpiration().before(new Date(System.currentTimeMillis())))
                    throw new Exception(); //Here trow exception.
                List<String> roleList = Arrays.asList(roles.split("\\s*,\\s*"));
                List<GrantedAuthority> grantedAuths = new ArrayList<GrantedAuthority>();
                for (int i = 0; i < roleList.size(); i++) {
                    System.out.println(roleList.get(i));
                    SimpleGrantedAuthority abv = new SimpleGrantedAuthority(roleList.get(i));
                    grantedAuths.add(abv);
                }
                System.out.println(grantedAuths);
                return user != null ? new UsernamePasswordAuthenticationToken(user, null, grantedAuths) : null;
            }
            return null;
        }catch (Exception e){
            System.out.println(e);
            return null;
        }
    }

}

How we implemented is -

  1. First time user logs in we send them a token and a refresh token.
  2. Client side then uses the 'token' in the header to make further API calls.
  3. At client side, we maintain e countdown of 15 minutes (which is lesser than the expiry time of the main token), after which from the client side we send a request to the server with both token and refresh token.
  4. After getting a valid refresh token along with the main token, the server sends back a new token with increased exipiry time.

Hope this helps.

Basically refresh_token is used for giving back a valid access_token to the user upon request. And refresh_tokens are usually long-lived rather than short-lived.

Personally, my design for securing a RESTful API is just to let them request the access_token to my endpoint ie https://api.example.com/oauth/token every time , I don't provide a refresh_token because the idea for me is just to let them in into the resource, nothing else. And usually, the requesting resource will not be staying for so long on a particular session. For the other concerns of the server getting too many requests on the same user/session, you can implement a rate-limiting to your servers or token endpoint.

I based my API security implementations on PayPal and JHipster . They do not provide refresh_tokens to their respective RESTful API implementations, because in the end, refresh_tokens are optional to be used, and it's just a matter of what you want to achieve upon securing your RESTful endpoints.

For more information about refresh_token you can these links: When to use JWT Tokens and Understanding refresh tokens .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM