프로젝트

세션 로그인 구현 복습

gitofjy 2022. 11. 22. 19:32

저번 프로젝트 때는 세션을 활용해 로그인을 구현했었다.

당시에는 서비스를 배포까지 계획이 없었기 때문에 세션으로도 충분했다.

하지만 굉장히 대충 만든 로그인이었고 이번 프로젝트에서는 JWT 방법을 이용하고자 한다.

또한 가능하다면 카카오/구글 등으로도 로그인을 가능하게 구현하는 것이 목표이다.

 

JWT 로그인 구현 방식에 대해 간략하게 찾아보니... 대충 봐도 어려웠다.

이왕 공부하는거 세션 로그인부터 시작해서 총체적으로 정리해야겠다.

 

 

 


 

저번 프로젝트 때 로그인은 아래와 같은 코드로 구현했다.

 

1. controller

@Controller
public class LoginController {
	
	private LoginService service;
	
	@Autowired
	public LoginController(LoginService service) {
		this.service = service;
	}
	
	@GetMapping(value="/login")
	public String login(HttpServletRequest request) {
		return "login";
	}
	
	@PostMapping(value="/loginok")
	public void loginok(HttpSession session, HttpServletResponse resp, HttpServletRequest req, LoginDTO dto, Model model) {
		
		LoginDTO result = service.login(dto);
		
		try {
			
			if (result != null) {
				session.setAttribute("result", result);
				resp.sendRedirect("/web/dashboardall");
			} else {
				session.removeAttribute("result");
				resp.setCharacterEncoding("UTF-8");
				resp.setContentType("text/html; charset=UTF-8");
				PrintWriter out = resp.getWriter();
				out.println("<script>alert('아이디 또는 비밀번호가 틀렸습니다.'); location.href='/web/login';</script>");
				out.flush();	
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@GetMapping(value="/logout")
	public String logout(HttpSession session, HttpServletRequest req) {
		session.removeAttribute("result");
		return "redirect:/login";
	}
	
}

 

2. DAO

public interface LoginDAO {

	LoginDTO login(LoginDTO dto);

}

 

3. DAOImpl

@Repository
public class LoginDAOImpl implements LoginDAO {

	private SqlSessionTemplate template;
	
	@Autowired
	public LoginDAOImpl(SqlSessionTemplate template) {
		this.template = template;
	}

	@Override
	public LoginDTO login(LoginDTO dto) {
		return this.template.selectOne("login.login", dto);
	}

}

 

4. DTO

import lombok.Data;

@Data
public class LoginDTO {
	
	private String employeeseq;
	private String ename;
	private String role;
	private String email;
	private String pw;
	private String position;
	private String tname;
	private String pname;
	private String pjsdate;
	private String pjfdate;
	private String pstate;
	private String levelseq;

}

 

5. Service

public interface LoginService {

	LoginDTO login(LoginDTO dto);

}

 

6. ServiceImpl

@Service
public class LoginServiceImpl implements LoginService {

	private LoginDAO dao;
	
	@Autowired
	public LoginServiceImpl(LoginDAO dao) {
		this.dao = dao;
	}

	@Override
	public LoginDTO login(LoginDTO dto) {
		return dao.login(dto);
	}

}

 

HttpSession을 이용해 로그인을 구현했고 장점은 HttpSession을 필요할 때만 생성하는 것이 가능하다는 점이다.

로그아웃하면 해당 세션을 제거하고 다시 로그인 페이지로 이동하도록 코드를 작성했다.

 

이 세션 정보를 이용해서 로그인한 사람의 직책에 따라 다른 메뉴가 보이도록 jsp 코드를 작성했다.

이런 부분을 구현하기 위해 처음 로그인 시 세션에 최대한 많은 정보를 저장했다.

구현하다가 필요한 정보가 있으면 DB 조합으로 만드는 게 아니라 세션에 정보를 추가했다.

보안 등 여러 요소를 고려하지 않았고 일단 로그인이 되는기 위한 코드였다.

그러다 보니 이 과정에서 공부하고 배운 것이 없는 것 같다.

 

<!-- 관리자 -->
<li class="nav-item admin">
    <a class="nav-link collapsed admin" data-toggle="collapse" data-target="#collapseAdmin" aria-expanded="true" aria-controls="collapseAdmin"> 
        <i class="fas fa-fw fa-cog admin"></i> <span class="admin">관리자</span>
    </a>
	<div id="collapseAdmin" class="collapse" aria-labelledby="headingOne" data-parent="#accordionSidebar">
		<div class="bg-white py-2 collapse-inner rounded">
			<a class="collapse-item " href="/web/adminuser">사용자 관리</a>
			<a class="collapse-item " href="/web/adminproject">프로젝트 관리</a>
		</div>
	</div>
</li>
<script>
$(function() {
		
	var role = "${sessionScope.result.role}";
	var levelseq = "${sessionScope.result.levelseq}";
		
	if (levelseq == 1) {
		$(".admin").show();
	} else {
		$(".admin").hide();
	}
		
	if (role == "PL") {
		 $(".adminProject").show();
	} else {
		 $(".adminProject").hide();
	}
		
});
</script>

 

 

로그인 상태 유지하는 2가지 방법

1. 요청할 때 사용자 정보를 쿼리 파라미터로 전달하기

> 번거롭고 식별 가능한 사용자 정보를 쿼리 파라미터에 노출하는 것은 보안상 위험하다.

2. 쿠키에 사용자 정보 담아서 사용하기

> 서버에서 로그인 성공 시 HTTP 응답에 쿠키를 담아 브라우저에 전달, 브라우저는 쿠키를 지속적으로 서버에 보내서 서버는 사용자를 식별할 수 있다.

3. 쿠키에 세션 정보 담아서 사용하기

 

 

쿠키 종류

1. 영속 쿠키 : 만료 날짜까지 유지

2. 세션 쿠키 : 브라우저 종료 시까지만 유지

 

 

쿠키의 보안 문제

1. 쿠키 값은 임의로 변경 가능하다

> 클라이언트가 쿠키를 강제로 변경하면 다른 사용자가 됨

> 웹브라우저 개발자 모드 Application Cookie 변경으로 확인 가능

2. 쿠키에 보관된 정보를 훔쳐갈 수 있다.

> 쿠키에 개인 정보 등이 있다면 이 정보가 웹 브라우저에 보관되고 네트워크 요청마다 계속 클라이언트 서버로 전달됨

> 쿠키의 정보가 나의 로컬 PC 혹은 네트워크 전송 구간에서 해킹당할 수 있다.

3. 해커가 쿠키를 훔쳐가면 평생 사용할 수 있다.

 

 

 


* 지금까지 내가 말하는 session과 쿠키는 같은 것? 세션 쿠키 / 영속 쿠키였던 것 같다

> 네트워크에 대한 지식이 없어 모르는 것 같다. 적어도 이 부분은 찾아서 정리 하기

* 보통은 세션 정보를 쿠키에 저장해 로그인을 구현하는 것 같다

> 이 방법으로 다시 구현해 보기

* 스프링 시큐리티를 이용해 로그인을 구현하는 것도 좋은 방법인 것 같다


 

참고

https://develop-writing.tistory.com/m/87

https://catsbi.oopy.io/0c27061c-204c-4fbf-acfd-418bdc855fd8

https://jaehoney.tistory.com/67

 

728x90