Implementing Token Generation and Validation in a Java Backend Using JWT
This article explains how to generate, store, and validate anti‑duplicate submission tokens in a Java web application by using a custom TokenProcessor, TokenTools utilities, and a JWT‑based OAuthTokenManager, covering both frontend button handling and backend verification logic.
Purpose : Prevent duplicate form submissions in a Java web project by generating a unique token on the server and validating it on each request.
Technology selection : Use the open‑source JWT (JSON Web Token) architecture.
Overview : When a client submits sensitive data, rapid repeated clicks can cause multiple identical submissions. The solution combines a front‑end button lock with a back‑end token check.
Solution :
Front‑end: hide or disable the submit button immediately after clicking.
Back‑end: verify each request by comparing a token sent from the client with the token stored in the server session.
Core code – Token generation utility :
/**
* 生成Token的工具类
*/
package red.hearing.eval.modules.token;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Random;
import sun.misc.BASE64Encoder;
public class TokenProccessor {
private TokenProccessor() {}
private static final TokenProccessor instance = new TokenProccessor();
public static TokenProccessor getInstance() { return instance; }
public String makeToken() {
String token = (System.currentTimeMillis() + new Random().nextInt(999999999)) + "";
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(token.getBytes());
BASE64Encoder encoder = new BASE64Encoder();
return encoder.encode(md5);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}Token utility for session handling :
package red.hearing.eval.modules.token;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang3.StringUtils;
public class TokenTools {
public static void createToken(HttpServletRequest request, String tokenServerkey) {
String token = TokenProccessor.getInstance().makeToken();
request.getSession().setAttribute(tokenServerkey, token);
}
public static void removeToken(HttpServletRequest request, String tokenServerkey) {
request.getSession().removeAttribute(tokenServerkey);
}
public static boolean judgeTokenIsEqual(HttpServletRequest request, String tokenClientkey, String tokenServerkey) {
String token_client = request.getParameter(tokenClientkey);
if (StringUtils.isEmpty(token_client)) return false;
String token_server = (String) request.getSession().getAttribute(tokenServerkey);
if (StringUtils.isEmpty(token_server)) return false;
if (!token_server.equals(token_client)) return false;
return true;
}
}OAuth token manager (JWT based) :
public class OAuthTokenManager {
private String APP_ID = "";
private String APP_SECRET = "";
private String KEY_SING = ""; // used for Redis storage
public static final int MINUTE_TTL = 60*1000;
// ... other TTL constants ...
private static OAuthTokenManager single = null;
public static OAuthTokenManager getInstance() {
if (single == null) single = new OAuthTokenManager();
return single;
}
private String generalKey() {
String stringKey = APP_ID + APP_SECRET;
byte[] encodedKey = Base64.decodeBase64(stringKey);
return new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
}
public String createToken(String subject, long ttlMillis) {
SignatureAlgorithm alg = SignatureAlgorithm.HS256;
Date now = new Date();
JwtBuilder builder = Jwts.builder()
.setId(APP_ID)
.setIssuedAt(now)
.setSubject(subject)
.signWith(alg, generalKey());
if (ttlMillis >= 0) {
Date exp = new Date(now.getTime() + ttlMillis);
builder.setExpiration(exp);
}
return builder.compact();
}
public Claims validateToken(String token) throws Exception {
return Jwts.parser().setSigningKey(generalKey()).parseClaimsJws(token).getBody();
}
// ... other helper methods ...
}Controller example for token issuance and validation :
@Controller
@RequestMapping("/oAuthToken")
public class OAuthToken {
@RequestMapping(params = "token", method = RequestMethod.GET)
@ResponseBody
public Object token(@RequestParam("grant_type") String grant_type,
@RequestParam("appid") String appid,
@RequestParam("secret") String secret,
HttpServletResponse response) {
Map
map = new HashMap<>();
if ("client_credentials".equals(grant_type)) {
OAuthTokenManager mgr = OAuthTokenManager.getInstance();
String token = mgr.token(appid, secret, null);
map.put("access_token", token);
map.put("expires_in", OAuthTokenManager.MINUTE_TTL/1000);
}
return map;
}
// loginAuth2 and index methods omitted for brevity
}Usage steps :
Call TokenTools.createToken(request, "tokenKey") before rendering the page; the token is stored in the session.
When the client submits the form, include the token (retrieved from the session) as a hidden field.
On the server side, invoke TokenTools.judgeTokenIsEqual(request, "clientToken", "tokenKey") ; if it returns false, reject the request.
Note : tokenClientkey and tokenServerkey are user‑defined and must match between front‑end and back‑end.
Dependency (Maven):
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.