Comprehensive Guide to User Login Flow, Token Management, and Anonymous Access in Backend Systems
This article explains the complete user login process, including mobile verification, token generation, token expiration policies, request‑rate limiting with Redis, anonymous request handling, blacklist management, and provides full Java Spring code examples for implementing these backend authentication mechanisms.
Preface
This article introduces the user login flow and its technical implementation through diagrams and code, covering user login, verification, token acquisition, and related blacklist and anonymous interface handling.
Business Diagram
The login process involves user registration and verification; a flowchart illustrates handling of new and existing users.
Process Interpretation
Client – Login Interface (usually mobile SMS verification)
Enter phone number
Send verification code
Enter verification code
Check "auto‑register new user"
Server – User Verification
Validate phone number and verification code
Check if user exists (create initial profile if not)
Generate token after successful verification
Return token to client
User Information Design
Verification Flow Diagram
The login verification involves two APIs and two caches: (1) the verification‑code API sends an SMS and stores the code with an expiration time; (2) the login API reads the cache, validates the code, generates a token, and returns it to the client, which then includes the token in subsequent request headers.
Token Expiration Time
Token lifetimes differ by client type: mobile apps typically receive a week‑long token, while web tokens expire in a few hours. You can separate app and web login interfaces or decide based on request‑header information.
Business Request Token Validation
After login, each client request carries the token. A gateway validates the token by looking up the cached user information and, upon success, injects user ID, account, and nickname into request headers for downstream services.
Logout Operation
The client calls a logout API with the token; the API deletes the token’s cache entry and returns a 401 response, prompting the client to redirect to the login page.
Anonymous Requests (No Login)
Two common solutions for anonymous access: (1) an authorized token with request‑rate limits; (2) path‑based regex rules that allow certain endpoints to bypass token validation.
Solution 1: Authorized Token with Rate Limiting
Advantages: traceability and controllable request volume; Disadvantages: additional coding and configuration.
Technical Implementation
Provide a management page for authorized tokens, specifying token value and allowed requests per minute.
CRUD operations store tokens in a cache (e.g., a map where key is the token and value is the limit).
Use a one‑minute expiration cache for counting requests.
This upgrade builds on the previous verification flow.
Request Count Check Code Implementation
import org.springframework.beans.factory.annotation.Autowired;<br/>import org.springframework.data.redis.core.RedisTemplate;<br/>import org.springframework.stereotype.Component;<br/><br/>import java.util.concurrent.TimeUnit;<br/><br/>/**<br/> * Authorized token request limit cache<br/> *<br/> * @author 热黄油啤酒<br/> * @since 2021-11-01<br/> */<br/>@Component<br/>public class AuthTokenRequestLimitCache {<br/><br/> @Autowired<br/> private RedisTemplate<String, Integer> redisTemplate;<br/><br/> private static final String AUTH_TOKEN_LIMIT_KEY_PREFIX = "auth_token_limit";<br/><br/> /**<br/> * Increment request count and check if it exceeds the limit<br/> * @param token<br/> * @return whether to allow the request<br/> */<br/> public boolean incrementWithCheck(String token) {<br/> // 1. Get the limit for the token; null means the token is no longer authorized<br/> Integer limit = getLimit(token);<br/> if (limit == null) {<br/> return false;<br/> }<br/> // 2. Build cache key and read the current count<br/> String key = String.join(":", AUTH_TOKEN_LIMIT_KEY_PREFIX, token);<br/> Integer count = redisTemplate.opsForValue().get(key);<br/> // 3. If no count, initialize it and set 1‑minute expiration<br/> if (count == null) {<br/> redisTemplate.opsForValue().increment(key);<br/> redisTemplate.expire(key, 1L, TimeUnit.MINUTES);<br/> return true;<br/> }<br/> // Increment and compare with limit; return false if exceeded<br/> Long inc = redisTemplate.opsForValue().increment(key);<br/> return inc <= limit;<br/> }<br/><br/> /**<br/> * Retrieve the configured limit for a token<br/> */<br/> public Integer getLimit(String token) {<br/> Object limit = redisTemplate.opsForHash().get("auth_token_limit", token);<br/> return limit == null ? null : (Integer) limit;<br/> }<br/>}<br/>Authorized interfaces usually allow only GET operations; data‑modifying actions are typically disallowed.
Solution 2: Request Path Regex Validation
Configure anonymous endpoint patterns in the gateway; requests matching the patterns are allowed without token verification, while others undergo normal authentication.
Blacklist
Implement a blacklist as the final security layer: provide a UI button to add user IDs to a Redis set, check the set during login, and if a logged‑in user is blacklisted, delete their token cache and return 401.
Summary
The user authentication system is fundamental, yet many developers may not have built one from scratch; this article offers a complete overview of login flow, token handling, rate limiting, anonymous access, and blacklist strategies.
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.
