Secure API Authentication: Token vs Signature with Java Code

This article compares token-based and signature-based API authentication methods, discusses their advantages and drawbacks, and provides complete Java code examples—including JWT token utilities, authentication interceptors, and signature verification—to help developers implement robust API security in real-world projects.

macrozheng
macrozheng
macrozheng
Secure API Authentication: Token vs Signature with Java Code

Abstract

In real business development, we often need to integrate with third‑party services such as Alipay, WeChat Pay, or AMap. When a startup grows, other companies may start calling your APIs, so you must design and protect your API interfaces.

Solution Overview

The most common solutions are two:

Token scheme

Interface signature

1. Token Scheme

The token scheme is the most widely used authentication method on the web. After a user logs in, the server generates a unique token that the client includes in the request header for subsequent API calls. The server validates the token before processing the request.

Typical steps:

After successful login, the server creates a token.

The client sends the token in the request header for each API call.

The server verifies the token’s validity; only valid tokens proceed to business logic.

Tokens are usually stored in Redis with a limited lifetime (e.g., 2 hours). When the token expires, the user must log in again to obtain a new token.

Advantages: simple, effective against packet sniffing and data scraping.

Drawbacks: when request volume is high, token expiration can cause many failed requests, especially during token refresh.

2. Interface Signature

Interface signature works by signing request parameters according to a predefined rule and placing the signature in the request header. The server recomputes the signature and compares it with the client’s value.

Core parameters:

appid – application ID, paired with appsecret for signing.

timestamp – request timestamp; must be within 5 minutes of the server time.

nonce – a random string to prevent replay attacks.

signature – the final signature string.

Signature generation consists of two MD5 steps:

// Step 1
String param1 = requestMethod + requestUrl + requestBody;
String param1Hash = md5(param1);
// Step 2
String param2 = appsecret + timestamp + nonce + param1Hash;
String signature = md5(param2);

The resulting signature is sent in the header and verified on the server.

Practical Implementation

Token Implementation

JwtTokenUtil defines constants for the Authorization header, token prefix, secret key, and expiration time, and provides methods to create and verify JWT tokens.

public class JwtTokenUtil {
    public static final String AUTH_HEADER_KEY = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer ";
    public static final String KEY = "q3t6w9z$C&F)J@NcQfTjWnZr4u7x";
    public static final Long EXPIRATION_TIME = 1000L*60*60*2;
    // createToken and verifyToken methods...
}

In the login controller, a token is generated and placed in the response header.

@RequestMapping(value = "/login", method = RequestMethod.POST,
                produces = {"application/json;charset=UTF-8"})
public UserVo login(@RequestBody UserDto userDto, HttpServletResponse response) {
    // ...validate user...
    String token = JwtTokenUtil.createToken(JSONObject.toJSONString(userToken));
    response.setHeader(JwtTokenUtil.AUTH_HEADER_KEY, token);
    // return user info...
}

An AuthenticationInterceptor extracts the token from the header, verifies it, and stores the user information in a thread‑local context.

public class AuthenticationInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        String token = request.getHeader(JwtTokenUtil.AUTH_HEADER_KEY);
        // verify token and set user context...
        return true;
    }
    // afterCompletion removes the context...
}

Signature Implementation

A SignInterceptor validates appid, timestamp, nonce, and signature. It recomputes the signature using SignUtil and checks for replay attacks with Redis.

public class SignInterceptor implements HandlerInterceptor {
    @Autowired private AppSecretService appSecretService;
    @Autowired private RedisUtil redisUtil;
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
                             Object handler) throws Exception {
        // validate appid, timestamp, nonce, signature...
        String signResult = SignUtil.getSignature(method, url, body,
                timestamp, nonce, appSecret);
        if (!signature.equals(signResult)) {
            throw new CommonException("Signature verification failed");
        }
        // prevent duplicate requests...
        return true;
    }
}

SignUtil performs the two‑layer MD5 signing.

public class SignUtil {
    public static String getSignature(String method, String url, String body,
                                      String timestamp, String nonce, String appSecret) {
        String requestStr1 = method + url + body + appSecret;
        String signResult1 = DigestUtils.md5Hex(requestStr1);
        String requestStr2 = appSecret + timestamp + nonce + signResult1;
        return DigestUtils.md5Hex(requestStr2);
    }
}

Conclusion

Both token and signature schemes can protect APIs from tampering and unauthorized calls, but they do not encrypt request or response data. For full security, encrypt parameters (e.g., RSA, AES) and use HTTPS in production.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaJWTtoken authenticationAPI SecurityHTTPSsignature
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.