현재 나는
그래서 생각한건
레디스의 키를
{사용자 이메일 : {deviceId : 리프레쉬 토큰} } 와 같은 식으로 사용하는 것
public class RedisAuthDAO {
static Map<String, Map<String, String>> userRefreshTokens = new HashMap<>();
public void storeRefreshToken(String username, String deviceId, String refreshToken) {
Map<String, String> userTokens = userRefreshTokens.get(username);
// 사용자의 이름을 키로 하는 맵에서, 그 안에 이중 맵으로 {아이디, 리프레쉬 토큰} 을 저장
if (userTokens == null) {
userTokens = new HashMap<>();
userRefreshTokens.put(username, userTokens);
}
userTokens.put(deviceId, refreshToken);
}
public String getRefreshToken(String username, String deviceId) {
Map<String, String> userTokens = userRefreshTokens.get(username);
return userTokens != null ? userTokens.get(deviceId) : null;
}
public void removeRefreshToken(String username, String deviceId) {
Map<String, String> userTokens = userRefreshTokens.get(username);
if (userTokens != null) {
userTokens.remove(deviceId);
}
}
}
유효기간, 듀레이션이 적절히 적용이 안된다면?
디바이스 아이디를 가져오는 것이 어렵다. 웹에서는 특히 그게 어려움 (앱은 그렇지 않다고 한다)
그렇다면 로컬 스토리지나 쿠키에 사용자를 식별할 디바이스 아이디를 입력해줘야 한다.
클라이언트 측에서 "브라우저의 이름" 을 가져오면, 그 이름과 사용자의 이메일을 붙여서 로컬 스토리지에 저장해주자.
function getBrowserName() {
let userAgent = navigator.userAgent;
if (userAgent.indexOf("Firefox") > -1) {
return "Firefox";
} else if (userAgent.indexOf("MSIE") > -1 || userAgent.indexOf("Trident") > -1) {
return "Internet Explorer";
} else if (userAgent.indexOf("Edge") > -1) {
return "Edge";
} else if (userAgent.indexOf("Chrome") > -1) {
return "Chrome";
} else if (userAgent.indexOf("Safari") > -1) {
return "Safari";
} else {
return "unknown";
}
}
let emailAddress = "user@example.com";
let browserName = getBrowserName();
let combinedIdentifier = emailAddress + "-" + browserName;
localStorage.setItem("uniqueIdentifier", combinedIdentifier);
로컬 스토리지는 브라우저마다 별도로 가지므로, 위와 같이 클라이언트측에서 셋 한 후에 "LoginRequestDto" 에서 브라우저의 이름을 가져오면 될 듯 하다. 아니면 헤더에 Browser-name 이라는 키로 브라우저를 식별할 수 있도록 하던가.
그렇다면 백단에서는 아래와 같이 될 것
@RestController
@RequestMapping
public class UserController {
// ...
@PostMapping("/login")
public ResponseEntity<?> login(@RequestBody LoginRequestDto loginRequestDto) {
// "browserName" 필드를 포함하는 LoginRequest 객체가 있다고 가정
String browserName = loginRequestDto.getBrowserName();
// ...
}
}
@RestController
@RequestMapping
public class UserController {
// ...
@PostMapping("/login")
public ResponseEntity<?> login(HttpServletRequest request) {
// 클라이언트 측 JavaScript에서 헤더에 "Browser-Name"을 포함하여 전송했다고 가정
String browserName = request.getHeader("Browser-Name");
// ...
}
}