wuyouzhuguli/SpringAll · error · Exception
请在请求头中设置deviceId
Error message
请在请求头中设置deviceId
What it means
Generic java.lang.Exception thrown by RedisCodeService.key when the 'deviceId' request header is blank. The Redis key for an SMS code is 'SMS_CODE:' + deviceId + ':' + mobile, so deviceId is mandatory to namespace codes per device. This is the project-64 Redis-backed variant of SMS code storage (replaces the session-based approach).
Source
Thrown at 64.Spring-Security-OAuth2-Customize/src/main/java/cc/mrbird/security/service/RedisCodeService.java:56
* @return 验证码
*/
public String get(ServletWebRequest request, String mobile) throws Exception {
return redisTemplate.opsForValue().get(key(request, mobile));
}
/**
* 移除验证码
*
* @param request ServletWebRequest
*/
public void remove(ServletWebRequest request, String mobile) throws Exception {
redisTemplate.delete(key(request, mobile));
}
private String key(ServletWebRequest request, String mobile) throws Exception {
String deviceId = request.getHeader("deviceId");
if (StringUtils.isBlank(deviceId)) {
throw new Exception("请在请求头中设置deviceId");
}
return SMS_CODE_PREFIX + deviceId + ":" + mobile;
}
}
View on GitHub (pinned to 614d2578d9)
Solutions
- Send a non-empty 'deviceId' request header on both GET /code/sms and POST /login/mobile (and any route through SmsCodeFilter).
- On mobile, use a stable per-install identifier (IDFV/Android ID/UUID persisted on first launch) as deviceId.
- Header names are case-insensitive per HTTP, but the value must be non-blank.
- Consider throwing a domain-specific exception instead of generic Exception for cleaner handling.
Example fix
// before
// fetch('/code/sms?mobile=13800000000')
// after
fetch('/code/sms?mobile=13800000000', {
headers: { 'deviceId': deviceUuid }
}); Defensive patterns
Strategy: validation
Validate before calling
// Persist a stable deviceId and attach it to every SMS-related request.
let deviceId = localStorage.getItem('deviceId');
if (!deviceId) { deviceId = crypto.randomUUID(); localStorage.setItem('deviceId', deviceId); }
function smsHeaders() { return { deviceId }; }
// use on GET /code/sms and POST /login/mobile Try / catch
try { await sendSms(mobile); }
catch (e) {
if (/deviceId/.test(e.message)) { ensureDeviceIdHeader(); retry(); }
else handleError(e);
} Prevention
- Generate and persist deviceId on first app launch; reuse it.
- Attach deviceId on both /code/sms and /login/mobile.
- Consider a domain exception type instead of generic Exception on the server.
When it happens
Trigger: Any call to RedisCodeService.save/get/remove (i.e. /code/sms generation or /login/mobile validation) without a 'deviceId' request header, or with an empty/whitespace value.
Common situations: Frontend/Postman omitted the deviceId header for the SMS endpoints; mobile app not sending a device identifier; header name casing/typo (Device-Id vs deviceId).
Related errors
- Authentication method not supported: {}
- Authentication method not supported: {method}
- 未找到与该手机号对应的用户
- 验证码不能为空!
- 验证码不存在!
AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14).
Data as JSON: /api/errors/a42f10f70d7bce37.
Report an issue: GitHub.