JSP

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(4) - 로그인 하기

김마리님 2020. 5. 29. 16:07

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(3) - 부트스트랩을 이용한 웹 폼 만들기

 

Servlet 과 JSP를 이용한(모델2 형식) 블로그 만들기(3) - 부트스트랩을 이용한 웹 폼 만들기

웹페이지를 만들다보면 CSS 덕분에 시간이 다 가는 경우가 있다. 우리는.. 일단 프론트엔드가 위주가 아니므로 편리한 부트스트랩을 이용하고자 한다. 부트스트랩은 트위터가 만든 프론트엔드 ��

itstudy-mary.tistory.com

 

※포스팅을 처음부터 보지 않으면 이해되지 않을 수도 있습니다!

 

저번 포스팅에서 웹에서 데이터베이스로 값을 넣는 방법을 선보였는데, 이것은 form action이 제대로 동작하고 있으면 그대로 들어갈 것이니 걱정하지 않아도 된다...!

이제 데이터베이스에서 값을 가져와서 로그인 해볼것이다.

앞서 login.jsp 파일을 생성할 때 action=loginProcaction="/blog/user?cmd=loginProc"로 걸어두었다. 이것은 user을 거치므로 컨트롤러를 거쳐 라우터를 확인할 것이다. cmd에 따라 바뀌는 라우터에 login을 할 때 어떤 일을 수행할 것인지, 그에 대한 코드를 작성해보자.

 

앞서 또 말했다시피 라우터에게 많은 일을 시키면 라우터가 본인의 역할이 희미해지므로, 라우터의 역할을 대신해줄 action을 만들 것이다.

 

- UserController.java의 router 메소드

	public Action router(String cmd) {
		if(cmd.equals("join")) {
			return new UsersJoinAction();
		}else if(cmd.equals("joinProc")) {
			//회원가입 진행 후 -> index.jsp 이동
			return new UsersJoinProcAction();
		}else if(cmd.equals("update")) {
			//회원 수정 페이지 이동(세션에 user object를 가지고 있을 예정)
		}else if(cmd.equals("updateProc")) {
			//회원 수정 진행 -> index 이동
		}else if(cmd.equals("delete")) {
			//회원 삭제 진행 후 -> 로그아웃 -> index.jsp
		}else if(cmd.equals("login")) {
			//회원 로그인 페이지로 이동
			return new UsersLoginAction();
		}else if(cmd.equals("loginProc")) {
			return new UsersLoginProcAction();
			//로그인 수행 -> 세션 등록 -> index.jsp
		}	

cmd를 login으로 받으면 login 화면을 출력하고, loginProc를 받으면 데이터베이스와 연동해서 로그인 하는 코드이다.

먼저 화면으로 이동하는 코드는 다음과 같다.

 

-UserLoginAction.java

package com.cos.blog.action.user;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.cos.blog.action.Action;

public class UsersLoginAction implements Action{
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 아이디 남기는 로직
		
		RequestDispatcher dis = request.getRequestDispatcher("user/login.jsp");
		dis.forward(request, response);
	}
}	

이 코드는 바로 로그인 화면으로 포워딩 해줄 것이다.

또, 로그인 할 때 데이터베이스로 repository로 이동해줄 것은,

 

-UsersLoginProcAction.java

package com.cos.blog.action.user;

import java.io.IOException;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.cos.blog.action.Action;
import com.cos.blog.model.Users;
import com.cos.blog.repository.UsersRepository;
import com.cos.blog.util.Script;

public class UsersLoginProcAction implements Action {
	@Override
	public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		//0. 유효성 검사
		if(
				request.getParameter("username").equals("")||
				request.getParameter("username")==null||
				request.getParameter("password").equals("")||
				request.getParameter("password")==null 
			) {
				return ;
			}
		String username =request.getParameter("username");
		String password =request.getParameter("password");
		
		UsersRepository usersRepository = UsersRepository.getInstance();
		Users user= usersRepository.findByUsernameAndPassword(username,password);
		
		if(user!=null) {
			HttpSession session=request.getSession();
			session.setAttribute("principal", user);
			
			Script.href("로그인 성공", "/blog/board?cmd=home", response);
			
		}else {
			Script.back("로그인 실패", response);
		}
	}
}

먼저, 내가 입력받은 아이디와 비밀번호가 비었는지 확인하고, 비어있지 않다면 아이디와 비밀번호를 가져온다. 

레파지토리에 있는 메소드 중, 아이디와 비밀번호로 비교해주는 메소드에 값을 넣어서 결과값을 출력받는다.

이제 레파지토리에 이 값을 확인해줄 메소드를 만들자.

 

-UsersRepository.java 중 findByUsernameAndPassword 메소드

	public Users findByUsernameAndPassword(String username, String password) {
		final String SQL="select id, username, email, address, userprofile, userrole, createDate from users where username=? and password=?";
		Users user=null;
		try {
			conn=DBConn.getConnection();
			pstmt = conn.prepareStatement(SQL);
			//물음표 완성하기
			pstmt.setString(1, username);
			pstmt.setString(2, password);
			rs=pstmt.executeQuery();
			//if -> rs
			if(rs.next()) {
				user=new Users();
				user.setId(rs.getInt("id"));
				user.setUsername(rs.getString("username"));
				user.setEmail(rs.getString("email"));
				user.setAddress(rs.getString("address"));
				user.setUserProfile(rs.getString("userProfile"));
				user.setUserRole(rs.getString("userRole"));
				user.setCreateDate(rs.getTimestamp("createDate"));
			}
			return user;
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(TAG+"findByUsernameAndPassword : "+e.getMessage());
		}finally {
			DBConn.close(conn, pstmt);
		}
		
		return null;
	}

이 메소드는 매개변수로 문자열을 받아 SQL문의 ? 부분을 PrepareStatement를 통해 채워줄 것이다.

(statement보다 preparestatement를 이용하는 이유 중 가장 큰 장점이 아닐까!)

이 값을 받아 ResultSet 값을 받는다. 앞서 데이터베이스를 생성할때 username이 유일한 값(unique)으로 설정했으므로, 맞는 컬럼은 하나뿐일 것이다. 따라서 while문을 돌릴 필요 없이 if문으로 하나만 받으면 된다.

그런데 여기서 주의할 점이 있다.

값이 일치하기도 전에 새 객체를 띄워버리면 값이 일치하던지 아니던지 안에 내부에 값이 있다면 그 값을 리턴할 것이다. 그렇게 되면 해킹의 위험성이 높아지므로 값이 있을때만 객체를 생성하도록 if문이 true일때만 만들어지도록 if문 내부에서 객체를 만든다.

 

이 때 주의할 점은, 우리가 이 값을 세션에 저장할텐데, 세션 속에 비밀번호를 넣으면 보안의 위험성이 높아지므로 절대, 절대 비밀번호를 넣지 않도록 한다.

 

이 값은 다시 액션으로 돌아가서 객체가 비어있지 않으면, 로그인을 성공한다.

이 때 주의할 점이 있는데, 로그인을 할 때, 세션에 객체를 저징하지 않으면 재요청할때 로그인정보가 날아간다. 그렇기 때문에 객체를 반드시 세션에 넣어 주어야 한다. 또, 로그인이 성공했는지, 실패했는지를 확인하기 위해서는 경고창을 띄우는 것이 가장 좋은데, 이 역시 스크립트를 이용하여 띄워주도록 하자.

 

-Script.java의 로그인 성공 스크립트

	public static void href(String msg, String uri, HttpServletResponse response) {
		try {
			response.setCharacterEncoding("utf-8");
			response.setContentType("text/html; charset=utf-8");
			PrintWriter out = response.getWriter();
			 
			out.println("<script>");
			out.println("alert('"+msg+"');");
			out.println("location.href='"+uri+"';");
			out.println("</script>");
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

 

그러나 다시 메인페이지로 돌아가면 로그인 된줄 확인할 수 없을 것이다. 그렇기 때문에 마지막으로 받은 세션값 중 username을 화면에 띄우는 코드를 추가해보자

 

-home.jsp (세션 확인용 아이디를 추가한 코드)

<%@page import="com.cos.blog.model.Users"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="include/nav.jsp" %>

<%
 Users principal=(Users)session.getAttribute("principal");
%>

<h1>
	<% if(principal!=null){ %>
	<%= principal.getUsername() %>
	<% } %>
</h1>

<div class="container">

	<div class="card m-2" style="width:100%">
	  <div class="card-body">
	    <h4 class="card-title">제목이 들어가는 자리</h4>
	    <p class="card-text">본문 미리 보기...</p>
	    <a href="#" class="btn btn-primary">상세보기</a>
	  </div>
	</div>
	
	<div class="card m-2" style="width:100%">
	  <div class="card-body">
	    <h4 class="card-title">제목이 들어가는 자리</h4>
	    <p class="card-text">본문 미리 보기...</p>
	    <a href="#" class="btn btn-primary">상세보기</a>
	  </div>
	</div>
	
	<div class="card m-2" style="width:100%">
	  <div class="card-body">
	    <h4 class="card-title">제목이 들어가는 자리</h4>
	    <p class="card-text">본문 미리 보기...</p>
	    <a href="#" class="btn btn-primary">상세보기</a>
	  </div>
	</div>
</div>

<%@ include file="include/footer.jsp" %>

 

이 결과는 다음과 같다

- 로그인 하지 않을때의 home

 

 

-로그인 했을때의 메인페이지

다음처럼 세션에 값이 있으면 다음과 같은 값을 띄우게 된다.

반응형