mirror of https://github.com/halo-dev/halo
fix: correct device information update during account switch (#6483)
#### What type of PR is this? /kind bug /area core /milestone 2.19.x #### What this PR does / why we need it: 修复切换账号登录时设备信息更新不正确的问题 原因: 1. 使用 admin 账号登录,此时会记录 device_id 的 cookie 2. 退出登录,device_id 会保留在 cookie 中并随着新账号带到服务端 3. 服务端根据 device_id 查询当前设备是否有对应的记录,但是没有校验用户名是否与当前登陆的一致然后就去更新登录时间 4. 正确的处理是校验 device_id 是否有与之对应的记录并且用户名相同,如果不相同则认为是新设备重新生成 device_id **how to test it?** 1. 先清理 cookie 然后使用一个账号登录 2. 退出登陆并切换新账号登录 3. 检查新登录的账号的设备信息是否正确 #### Does this PR introduce a user-facing change? ```release-note 修复切换账号登录时设备信息更新不正确的问题 ```pull/6498/head
parent
f9615d072d
commit
87368df18a
|
@ -40,7 +40,7 @@ public class DeviceServiceImpl implements DeviceService {
|
|||
|
||||
@Override
|
||||
public Mono<Void> loginSuccess(ServerWebExchange exchange, Authentication authentication) {
|
||||
return updateExistingDevice(exchange)
|
||||
return updateExistingDevice(exchange, authentication)
|
||||
.switchIfEmpty(createDevice(exchange, authentication)
|
||||
.flatMap(client::create)
|
||||
.doOnNext(device -> {
|
||||
|
@ -61,10 +61,7 @@ public class DeviceServiceImpl implements DeviceService {
|
|||
.map(context -> context.getAuthentication().getName())
|
||||
.flatMap(username -> {
|
||||
var deviceId = deviceIdCookie.getValue();
|
||||
return updateWithRetry(deviceId, device -> {
|
||||
if (!device.getSpec().getPrincipalName().equals(username)) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return updateWithRetry(deviceId, username, device -> {
|
||||
var oldSessionId = device.getSpec().getSessionId();
|
||||
return exchange.getSession()
|
||||
.filter(session -> !session.getId().equals(oldSessionId))
|
||||
|
@ -78,9 +75,10 @@ public class DeviceServiceImpl implements DeviceService {
|
|||
});
|
||||
}
|
||||
|
||||
private Mono<Device> updateWithRetry(String deviceId,
|
||||
private Mono<Device> updateWithRetry(String deviceId, String username,
|
||||
Function<Device, Mono<Device>> updateFunction) {
|
||||
return Mono.defer(() -> client.fetch(Device.class, deviceId)
|
||||
.filter(device -> device.getSpec().getPrincipalName().equals(username))
|
||||
.flatMap(updateFunction)
|
||||
.flatMap(client::update)
|
||||
)
|
||||
|
@ -88,38 +86,41 @@ public class DeviceServiceImpl implements DeviceService {
|
|||
.filter(OptimisticLockingFailureException.class::isInstance));
|
||||
}
|
||||
|
||||
private Mono<Device> updateExistingDevice(ServerWebExchange exchange) {
|
||||
private Mono<Device> updateExistingDevice(ServerWebExchange exchange,
|
||||
Authentication authentication) {
|
||||
var deviceIdCookie = deviceCookieResolver.resolveCookie(exchange);
|
||||
if (deviceIdCookie == null) {
|
||||
return Mono.empty();
|
||||
}
|
||||
return updateWithRetry(deviceIdCookie.getValue(), (Device existingDevice) -> {
|
||||
var sessionId = existingDevice.getSpec().getSessionId();
|
||||
return exchange.getSession()
|
||||
.flatMap(session -> {
|
||||
var userAgent =
|
||||
exchange.getRequest().getHeaders().getFirst(HttpHeaders.USER_AGENT);
|
||||
var deviceUa = existingDevice.getSpec().getUserAgent();
|
||||
if (!StringUtils.equals(deviceUa, userAgent)) {
|
||||
// User agent changed, create a new device
|
||||
return Mono.empty();
|
||||
}
|
||||
return Mono.just(session);
|
||||
})
|
||||
.flatMap(session -> {
|
||||
if (session.getId().equals(sessionId)) {
|
||||
var principalName = authentication.getName();
|
||||
return updateWithRetry(deviceIdCookie.getValue(), principalName,
|
||||
(Device existingDevice) -> {
|
||||
var sessionId = existingDevice.getSpec().getSessionId();
|
||||
return exchange.getSession()
|
||||
.flatMap(session -> {
|
||||
var userAgent =
|
||||
exchange.getRequest().getHeaders().getFirst(HttpHeaders.USER_AGENT);
|
||||
var deviceUa = existingDevice.getSpec().getUserAgent();
|
||||
if (!StringUtils.equals(deviceUa, userAgent)) {
|
||||
// User agent changed, create a new device
|
||||
return Mono.empty();
|
||||
}
|
||||
return Mono.just(session);
|
||||
}
|
||||
return sessionRepository.deleteById(sessionId).thenReturn(session);
|
||||
})
|
||||
.map(session -> {
|
||||
existingDevice.getSpec().setSessionId(session.getId());
|
||||
existingDevice.getSpec().setLastAccessedTime(session.getLastAccessTime());
|
||||
existingDevice.getSpec().setLastAuthenticatedTime(Instant.now());
|
||||
return existingDevice;
|
||||
})
|
||||
.flatMap(this::removeRememberMeToken);
|
||||
});
|
||||
})
|
||||
.flatMap(session -> {
|
||||
if (session.getId().equals(sessionId)) {
|
||||
return Mono.just(session);
|
||||
}
|
||||
return sessionRepository.deleteById(sessionId).thenReturn(session);
|
||||
})
|
||||
.map(session -> {
|
||||
existingDevice.getSpec().setSessionId(session.getId());
|
||||
existingDevice.getSpec().setLastAccessedTime(session.getLastAccessTime());
|
||||
existingDevice.getSpec().setLastAuthenticatedTime(Instant.now());
|
||||
return existingDevice;
|
||||
})
|
||||
.flatMap(this::removeRememberMeToken);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in New Issue