Spring Boot에서 세션을 사용하는 방법에 대해서 알아볼게요.
Bean Scope를 활용하여 session 데이터를 편리하게 관리할 수 있는 방법을 알려드릴거에요.
굉장히! 간단합니다. 컴포넌트 하나만 추가하면 되요.
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
</dependencies>
build.gradle
dependencies {
implementation 'org.springframework.session:spring-session-core'
}
UserInfo
세션에 저장할 데이터 변수를 선언해줄거에요.
예제니깐 아주 간단하게 사용자의 아이디와 이름만 저장할게요.
- SCOP_SESSION : 객체가 한 세션에서 생명주기를 갖도록 Bean Scope를 session으로 설정해주세요.
- proxyMode=TARGET_CLASS : Bean Scope를 session으로 설정할 경우에는 proxyMode를 TARGE_CLASS로 설정해주어야 해요. 자세한 설명을 시작하면 배보다 배꼽이 커질 것 같아 생략하겠습니다. 궁금하신 분은 Spring Boot에서의 Proxy와 CGLIB를 이해하시면 도움이 될 것 같네요.
- Serializable : 중요한건 객체를 직렬화(Serializable)를 하여 자바 외부 시스템에서도 사용할 수 있도록 Byte 형태로 변환해줘야 해요. 그 이유는 외부 Redis와 같은 데이터베이스에 세션을 저장할 것이기 때문이죠. 외부에 저장하지 않고 애플리케이션 서버 내에 메모리에서 해결할 계획이라면 굳이 직렬화하지 않아도 됩니다.
@Getter
@Setter
@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
@ToString
public class UserInfo implements Serializable {
private static final long serialVersionUID = 1L;
private Long userId;
private String userNm;
}
UserController
위에서 만든 UserInfo를 사용하여 비즈니스에 적용만 하면 되요.
/user/signin: 아이디와 패스워드를 받아서 사용자 정보를 가져온 후 패스워드가 일치하면 userInfo 세션 객체에 정보를 저장
/user/session: 세션에 있는 사용자 데이터를 응답
@RestController
@RequestMapping("user")
public class UserController {
@Resource
private UserInfo userInfo;
@Autowired
private UsersRepo usersRepo;
@PostMapping("signin")
public UsersDoc signin(@RequestBody UsersDoc reqBody) {
String userId = reqBody.getUserId();
String passwd = reqBody.getPasswd();
UsersDoc doc = usersRepo.findByUserId(userId)
.filter((data) -> data.getPasswd().equals(passwd))
.orElseThrow(() -> new RestException(HttpStatus.NOT_FOUND, "Check your infomation."));
userInfo.setUserId(doc.getUserId());
userInfo.setUserNm(doc.getUserNm());
return doc;
}
@GetMapping("session")
public String get() {
return userInfo.toString();
}
}
테스트를 해볼게요.
서버를 실행하고 /user/signin을 호출해보세요.
그럼 서버에서 JSESSIONID를 발급해주어 쿠키에 들어가있는 것을 확인할 수 있죠?
이 서버를 호출할 때마다 클라이언트에서는 이 발급받은 JSESSIONID를 계속 보낼거에요.
서버에서는 JSESSIONID의 생명 주기 동안 UserInfo을 가져와서 로직을 처리할 수 있게 되죠.
/user/session을 호출해보면 userInfo 객체에 저장한 데이터를 확인할 수 있어요.
다른 클라이언트에서 호출해보면 JSESSIONID가 다르기 때문에 값을 확인할 수 없습니다.
application.yml
서버에서 발급해준 JSESSIONID가 몇 초 동안 유효한지 설정할 수 있어요.
아래처럼 30초로 지정하면 JSESSIONID가 만료되어 삭제되고 다시 Session에 데이터를 입력해주어야 하죠. (재로그인)
30분이라면 30m, 30시간이라면 30h겠죠?
server:
servlet:
session:
timeout: 30s
지금까지 Spring의 Bean Scope를 이용하여 세션에 데이터를 저장하고 가져오는 방법을 알아봤어요.
아무 설정도 하지 않았기 때문에 애플리케이션 서버 내부에 데이터가 저장이 되요.
이런 경우에는 서버를 증설하여 두 대 이상이 되었을 때 세션을 클러스터링해주어야하는 번거로움이 생기죠.
그래서 세션을 외부 서버에 저장하는 방법이 있습니다.
Spring Boot Session을 Redis, MongoDB, MySQL에 저장하는 방법은 아래 글을 참고해주세요.
'Backend > Spring' 카테고리의 다른 글
Spring Boot Session MongoDB 연동, 저장 (0) | 2019.10.16 |
---|---|
Spring Boot Session Redis 연동, 저장 (2) | 2019.10.16 |
Spring Boot 재시작 없이 반영 (DevTools) (0) | 2019.10.14 |
Spring Boot MongoDB 연동 (2) | 2019.10.11 |
Spring Boot 파일 업로드 MultipartFile (5) | 2019.10.07 |