Implementing QR Code Login with WebSocket in Spring Boot
This article walks through building a QR‑code based login system using Spring Boot, detailing database design, role analysis, required APIs, step‑by‑step implementation, and full Java and JavaScript code for generating QR codes, handling WebSocket communication, and confirming user authentication.
The tutorial begins by defining a User_Token table to record which user scanned the QR code, with fields such as uuid , userId , loginTime , createTime , and state indicating QR validity.
Three roles are identified for the QR‑code login flow: the Android/WeChat web client that scans the code, the PC client that displays the QR and waits for login, and the backend server that provides APIs and manages WebSocket connections.
Two REST endpoints are required: one to generate a QR code containing a UUID ( /getLoginQr ) and another to confirm the identity and check QR expiration ( /bindUserIdAndToken ).
The implementation steps are:
PC client calls the QR‑code generation API, receives the image stream and the UUID from the response header.
The web client scans the QR code, extracts the UUID, and displays a confirmation page.
After user confirmation, the web client calls the identity‑verification API with the UUID and user ID.
The server validates the token, updates the User_Token record, and pushes a success message to the PC client via WebSocket.
Java code for the QR‑code generation endpoint:
@RequestMapping(value = "/getLoginQr", method = RequestMethod.GET)
public void createCodeImg(HttpServletRequest request, HttpServletResponse response) {
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
try {
String uuid = userService.createQrImg();
response.setHeader("uuid", uuid);
QrCodeUtil.generate(uuid, 300, 300, "jpg", response.getOutputStream());
} catch (Exception e) {
e.printStackTrace();
}
}Front‑end JavaScript loads the QR image via XMLHttpRequest , extracts the UUID from the response header, and establishes a WebSocket connection using that UUID as the session identifier:
var xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET", getQrPath, true);
xmlhttp.responseType = "blob";
xmlhttp.onload = function () {
if (this.status == 200) {
var uuid = this.getResponseHeader("uuid");
// display QR image
// init WebSocket
initWebSocket(uuid);
}
};
xmlhttp.send();The WebSocket server is configured with Spring Boot by adding the spring-boot-starter-websocket dependency, a ServerEndpointExporter bean, and a @ServerEndpoint class that manages connections, broadcasts messages, and sends targeted notifications:
@ServerEndpoint("/websocket/{sid}")
@Component
public class WebSocketServer {
private static CopyOnWriteArraySet
webSocketSet = new CopyOnWriteArraySet<>();
private Session session;
private String sid = "";
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
this.session = session;
this.sid = sid;
webSocketSet.add(this);
// log connection
}
@OnMessage
public void onMessage(String message, Session session) {
// broadcast
for (WebSocketServer client : webSocketSet) {
client.sendMessage(message);
}
}
public void sendMessage(String message) throws IOException {
this.session.getBasicRemote().sendText(message);
}
// other lifecycle methods omitted for brevity
}The identity‑verification controller updates the token record, checks expiration, and uses WebSocketServer.sendInfo to push a JSON payload with login success data (userId, projId) to the PC client:
@RequestMapping(value = "/bindUserIdAndToken", method = RequestMethod.GET)
@ResponseBody
public Object bindUserIdAndToken(@RequestParam("token") String token,
@RequestParam("userId") Integer userId,
@RequestParam(required = false, value = "projId") Integer projId) {
try {
// validate token, update login time, etc.
WebSocketServer.sendInfo(jsonObject.toJSONString(), token);
return new SuccessTip(userService.bindUserIdAndToken(userId, token, projId));
} catch (Exception e) {
return new ErrorTip(500, e.getMessage());
}
}When the PC client receives the WebSocket message, it stores the session data and redirects the user to the desired page, completing the QR‑code login flow.
The article concludes with a reminder to explore the provided open‑source projects for deeper understanding and invites readers to discuss or ask questions.
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.