{"record":{"id":"9de2e3afd0b228cc","repo":"paascloud/paascloud-master","slug":"id","errorCode":null,"errorMessage":"设备id参数不能为空","messagePattern":"设备id参数不能为空","errorType":"validation","errorClass":"AppSecretException","httpStatus":400,"severity":"error","filePath":"paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/social/AppSingUpUtils.java","lineNumber":90,"sourceCode":"\t\tString key = getKey(request);\n\t\tif (!redisTemplate.hasKey(key)) {\n\t\t\tthrow new AppSecretException(\"无法找到缓存的用户社交账号信息\");\n\t\t}\n\t\tConnectionData connectionData = (ConnectionData) redisTemplate.opsForValue().get(key);\n\t\tConnection<?> connection = connectionFactoryLocator.getConnectionFactory(connectionData.getProviderId())\n\t\t\t\t.createConnection(connectionData);\n\t\tusersConnectionRepository.createConnectionRepository(userId).addConnection(connection);\n\n\t\tredisTemplate.delete(key);\n\t}\n\n\t/**\n\t * 获取redis key\n\t */\n\tprivate String getKey(WebRequest request) {\n\t\tString deviceId = request.getHeader(\"deviceId\");\n\t\tif (StringUtils.isBlank(deviceId)) {\n\t\t\tthrow new AppSecretException(\"设备id参数不能为空\");\n\t\t}\n\t\treturn \"pc:security:social.connect.\" + deviceId;\n\t}\n\n}\n","sourceCodeStart":72,"sourceCodeEnd":96,"githubUrl":"https://github.com/paascloud/paascloud-master/blob/781281a9503332ed3cef44ea618349d14230a127/paascloud-common/paascloud-security-app/src/main/java/com/paascloud/security/app/social/AppSingUpUtils.java#L72-L96","documentation":"AppSingUpUtils.getKey throws AppSecretException('设备id参数不能为空') when the request has no 'deviceId' header. The deviceId is required to build the Redis key ('pc:security:social.connect.' + deviceId) under which social connection data is cached. It is called by saveConnectionData and by getKey-based lookups in doPostSignUp.","triggerScenarios":"Any call to saveConnectionData(request, connection) or doPostSignUp(request, userId) with a WebRequest lacking a non-blank 'deviceId' header — e.g. request from a browser/desktop client that never sets deviceId, or header stripped by a proxy/gateway.","commonSituations":"Mobile app updated without sending the new required deviceId header; nginx or API gateway not forwarding custom headers; developer testing signup endpoints with curl/Postman and forgetting the header; web client performing social signup where deviceId was never generated.","solutions":["Set a unique, stable 'deviceId' header on every social-login and signup request.","If a gateway strips custom headers, whitelist/forward the deviceId header in your proxy configuration.","Generate and persist a deviceId on the client (e.g. UUID in local storage) on first launch.","For tests, include -H 'deviceId: <value>' in curl/Postman calls.","Consider falling back to session id or another stable identifier for web clients."],"exampleFix":"// before\nwebClient.post().uri(\"/social/signUp\").bodyValue(form); // no header\n// after\nwebClient.post().uri(\"/social/signUp\")\n    .header(\"deviceId\", deviceId)\n    .bodyValue(form);","handlingStrategy":"validation","validationCode":"String deviceId = request.getHeader(\"deviceId\");\nif (deviceId == null || deviceId.trim().isEmpty()) {\n    throw new IllegalArgumentException(\"deviceId header is required for social signup\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    appSingUpUtils.doPostSignUp(request, userId);\n} catch (AppSecretException e) {\n    if (e.getMessage().contains(\"设备id\")) {\n        response.sendError(400, \"deviceId header required\");\n    }\n}","preventionTips":["Generate and persist a deviceId on the client at first launch.","Attach deviceId to every social-login/signup request.","Ensure proxies/gateways forward the deviceId header.","Add an API-contract test asserting the header is present."],"tags":["java","spring-social","redis","missing-header","device-id"],"backgroundTag":"missing-required-header","analyzedSha":"781281a9503332ed3cef44ea618349d14230a127","analyzedAt":"2026-09-10T10:59:02.070Z","contentChangedAt":"2026-09-10T10:59:02.070Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}