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

  1. Send a non-empty 'deviceId' request header on both GET /code/sms and POST /login/mobile (and any route through SmsCodeFilter).
  2. On mobile, use a stable per-install identifier (IDFV/Android ID/UUID persisted on first launch) as deviceId.
  3. Header names are case-insensitive per HTTP, but the value must be non-blank.
  4. 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

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


AI-assisted analysis of wuyouzhuguli/SpringAll@614d2578d9 (2026-08-14). Data as JSON: /api/errors/a42f10f70d7bce37. Report an issue: GitHub.