-
세션 로그인 구현 복습프로젝트 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'프로젝트' 카테고리의 다른 글
웹 API를 위한 JSON vs XML (0) 2023.04.25 프로젝트 기본 환경설정 - 1 (0) 2023.01.18 REST와 REST API (0) 2022.12.26 스프링 프레임워크(Framework)에 대하여, 스프링부트? (0) 2022.12.04 API 와 오픈 API (0) 2022.11.22