【发布时间】:2021-03-01 13:59:16
【问题描述】:
我正在使用 RedisHttpSession,我的基本目标是在成功登录时将人员对象保存在会话对象中,在需要的地方检索它并在注销时销毁会话。
成功登录后,这就是我正在做的事情:
Staff staff = staffService.getEmailInstance(body.getEmailId());
request.getSession(true).setAttribute("staff", staff);
而注销就是这样:
request.getSession().invalidate();
在不同的控制器中,我正在调用此实用程序方法来检查员工是否已登录:util.isStaffLoggedIn(request, response, StaffRole.EDITOR); 如果员工已登录,则 API 继续执行,否则用户将被重定向到登录页面。
@Service
public class Util {
public boolean isStaffLoggedIn(HttpServletRequest request, HttpServletResponse response, StaffRole staffRole)
throws PaperTrueInvalidCredentialsException, PaperTrueJavaException {
Staff staff = (Staff) request.getSession().getAttribute("staff");
if (!isObjectNull(staff) && staff.getStaffRole().equals(staffRole)) {
return true;
}
invalidateSessionAndRedirect(request, response);
return false;
}
public void invalidateSessionAndRedirect(HttpServletRequest request, HttpServletResponse response)
throws PaperTrueJavaException, PaperTrueInvalidCredentialsException {
request.getSession().invalidate();
try {
response.sendRedirect(ProjectConfigurations.configMap.get("staff_logout_path"));
} catch (IOException e) {
throw new PaperTrueJavaException(e.getMessage());
}
throw new PaperTrueInvalidCredentialsException("Staff not loggedIn");
}
}
现在,当应用程序运行时,成功登录后会立即调用 get-jobs API。大多数时候request.getSession().getAttribute("staff") 方法工作正常并返回'staff' 对象,但偶尔会返回null。这不会经常发生,但确实会发生。我打印了会话 ID 以查看它们在注销后是否不同,并且确实如此。每次注销后,我都有一个新的会话 ID。我什至检查了我从数据库中检索到的人员对象是否为空,但它不是。
staff 对象已成功保存在会话中,但我无法在其他 API 中检索它。这是我的会话配置的样子:
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 10800)
public class SessionConfig {
HashMap<String, String> configMap = ProjectConfigurations.configMap;
@Bean
public LettuceConnectionFactory connectionFactory() {
int redisPort = Integer.parseInt(configMap.get("redis_port"));
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration(
configMap.get("redis_host"), redisPort);
redisStandaloneConfiguration.setPassword(configMap.get("redis_password"));
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("PTSESSIONID");
serializer.setSameSite("none");
serializer.setUseSecureCookie(!configMap.get("staff_logout_path").contains("localhost"));
return serializer;
}
}
如果我错过了什么,请告诉我。提前致谢。
更新 1
我不再使会话无效,我已将 request.getSession(true).setAttribute("staff", staff); 替换为 request.getSession().setAttribute("staff", staff);
我在 StaffController 中设置了“员工”并在 EditorController 中获取它。我是这样设置的:
@RestController
@RequestMapping(path = { "/staff" }, produces = "application/json")
public class StaffApiController {
private final HttpServletRequest request;
private final HttpSession httpSession;
@Autowired
private StaffService staffService;
@Autowired
StaffApiController(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
this.request = request;
this.httpSession = session;
}
@PostMapping("/login")
public ResponseEntity<StaffLoginResponse> login(@Valid @RequestBody StaffLoginBody body) {
StaffLoginResponse staffLoginResponse = new StaffLoginResponse();
try {
if (!staffService.isValidLogin(body.getEmailId(), body.getPassword())) {
throw new PaperTrueInvalidCredentialsException("Invalid Credentials");
}
Staff staff = staffService.getEmailInstance(body.getEmailId());
httpSession.setAttribute("staff", staff);
staffLoginResponse.setEmail(staff.getEmail()).setRole(staff.getStaffRole().getValue())
.setStaffID(staff.getId()).setStatus(new Status("Staff Login Successful"));
} catch (PaperTrueException e) {
httpSession.removeAttribute("staff");
staffLoginResponse.setStatus(new Status(e.getCode(), e.getMessage()));
}
return ResponseEntity.ok(staffLoginResponse);
}
@PostMapping("/logout")
public ResponseEntity<Status> logout() {
httpSession.removeAttribute("staff");
return ResponseEntity.ok(new Status("Staff Logged Out Successfully"));
}
}
【问题讨论】:
-
让我印象深刻的一件事是,您拨打的是
request.getSession(true)。如果不存在,这将创建一个新会话。您是要在这里创建一个新会话,还是希望它此时已经存在? -
@EleftheriaStein-Kousathana 我不想创建新会话。我只想将 Staff 对象保存到 Session 并在注销时将其删除。我已经用
getSession()替换了getSession(true),并且我没有在注销时使会话无效,而是在做removeAttribute("staff")。目前,如果我在会话中设置一个属性然后立即检索它,我会得到空值。但是,如果我刷新页面,我会在会话中获得该属性。我认为会话不会立即更新。 -
您在哪里获取和设置人员属性?例如在自定义过滤器或控制器中?
-
我在 StaffController 中设置它并在 EditorController 中获取它
-
对 StaffController 和 EditorController 的请求是异步的吗?还是先调用 StaffController,一旦调用成功,再调用 EditorController?
标签: java spring-boot spring-data-redis httpsession spring-session