问题是:我需要在不使用Spring Security的情况下实现身份验证机制。Stack:Sping Boot + React。我首先尝试在控制器中注册会话ID,并使用HashMap将会话ID绑定到用户名。当用户注册时,他们的会话ID将被记录并绑定到他们的用户名。如果用户退出,则会话将从Map中删除。
此外,我提出的唯一解决方案是使用JavaScript询问服务器HashMap中是否缺少会话ID,但结果证明这种方法是无效的。**
必须实现以下目标:如果用户在浏览器的第二个页签进入这个站点,那么如果他在第一个页签登录,他会自动登录到第二个页签,而且如果用户在第一个页签注销,那么第二个页签应该自动注销。
我该怎么做呢?
我的控制者:
import com.cleanyco.weblab4backend.model.User;
import com.cleanyco.weblab4backend.repository.UserRepository;
import com.cleanyco.weblab4backend.util.MD5PasswordEncoder;
import com.google.gson.Gson;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;
@RestController
public class UserController {
private static final Logger logger = Logger.getLogger(UserController.class.getName());
private final UserRepository userRepository;
public UserController(@Autowired UserRepository userRepository) {
this.userRepository = userRepository;
}
private final Map<String, String> activeSessions = new HashMap<>();
public String identificateSession(String sessionID) {
for (Map.Entry<String, String> userSession : activeSessions.entrySet()) {
if (userSession.getKey().equals(sessionID)) {
return userSession.getValue();
}
}
return null;
}
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@PostMapping("/signup")
public ResponseEntity<?> signup(HttpSession session, @RequestBody User user) {
User existingUser = userRepository.findUserByUsername(user.getUsername());
if (existingUser == null) {
logger.info("User wasn't found. Registering a new one...");
activeSessions.put(session.getId(), user.getUsername());
logger.info("Registered an active session. User: " + user.getUsername() + "; SessionID: " + session.getId());
user.setPassword(MD5PasswordEncoder.hash(user.getPassword()));
userRepository.save(user);
logger.info("User was successfully saved");
return new ResponseEntity<>(HttpStatus.OK);
} else {
logger.info("User with the same name already exists");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@PostMapping("/login")
public ResponseEntity<?> login(HttpSession session, @RequestBody User user) {
User existingUser = userRepository.findUserByUsername(user.getUsername());
if (existingUser != null) {
String userPassword = user.getPassword();
String hashedPassword = MD5PasswordEncoder.hash(userPassword);
if (existingUser.getPassword().equals(hashedPassword)) {
logger.info("User successfully logged in");
String activeUser = identificateSession(session.getId());
if (activeUser == null) {
activeSessions.put(session.getId(), user.getUsername());
}
return new ResponseEntity<>(HttpStatus.OK);
} else {
logger.info("Invalid password was provided");
return new ResponseEntity<>(HttpStatus.FORBIDDEN);
}
} else {
logger.info("User not found");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
private static final Gson gson = new Gson();
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@GetMapping(value = "/checksession", produces = MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<?> getActiveSession(HttpSession session) {
if (identificateSession(session.getId()) != null) {
String username = identificateSession(session.getId());
User user = userRepository.findUserByUsername(username);
return ResponseEntity.ok(gson.toJson(user));
} else {
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
}
}
@CrossOrigin(origins = "http://localhost:3000", allowCredentials = "true")
@GetMapping("/logout")
public ResponseEntity<?> logout(HttpSession session) {
String exitUser = identificateSession(session.getId());
if (activeSessions.remove(exitUser) == null) {
logger.info("An error occurred while logging out the user: user already logged out");
return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
} else {
activeSessions.remove(session.getId());
logger.info("User was successfully logged out. User: " + exitUser + "; SessionID: " + session.getId());
return new ResponseEntity<>(HttpStatus.OK);
}
}
}```
1条答案
按热度按时间yfwxisqw1#
要使用登录/注销同步处理多个浏览器窗口,请执行以下操作。
1.当用户登录时,在浏览器本地存储中设置一个标志。
1.用户注销时,重置/清除本地存储中的标志。
1.每次UI应用程序启动时,检查本地存储中的标志。如果设置了标志,则假定用户已登录,否则显示登录页面。
1.要同步用户注销,您需要实现一个方法,该方法将频繁轮询本地存储值,如果重置标记,则假定用户从另一个选项卡注销,并在当前选项卡中注销。