본문 바로가기
SPRING/SPRING 프로젝트

SPRING 프로젝트 - 펀딩 사이트 (3) : 로그인 화면 구현

by 스노위13 2022. 8. 29.

1. 내용 : 로그인하는 화면을 만들고 Controller에서 로그인 화면과 아이디와 비밀번호 검사 그리고 특정 조건에서 아래쪽에 빨간 글씨로 메세지가 나오게 구현하였음. 

2. 과정 중 특이점 : 로그인하는 자체는 수업시간에 해서 그리 어렵지 않았으나 수업시간 배운 내용만으론 로그인했을 때 또는 아이디나 비밀 번호를 틀렸을 때 내가 원하는 페이지로 바로 가질 못하고 메세지 화면으로 간 다음 거기에서 다시 버튼을 눌러 이동해야 한다는 문제가 있었다. 그래서 구글링을 하던 중 ModelAndView를 알게 되어 쉽게 문제를 해결할 수 있었다. 

3. 화면 및 코드 설명

1) 로그인 화면

아이디와 비밀번호로 로그인을 하는 화면 
https://ionic.io/ionicons 에서 제공하는 아이콘을 활용하여 따로 이미지 파일이 필요 없다.

로그인에 실패하거나 회원가입에 성공하면 로그인 버튼 아래에 메세지가 뜨도록 만들었다.

2) Login.jsp 코드

전체코드는 더보기로 확인해주세요!

더보기
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.security.SecureRandom" %>
<%@ page import="java.math.BigInteger" %>
<!DOCTYPE html>
<html>
<head>
<%@include file="/WEB-INF/inc/header.jsp" %>
<meta charset="UTF-8">
<title>Insert title here</title>
<link rel="stylesheet" type="text/css" href="<%=request.getContextPath() %>/resources/css/member/login.css" />
<script type="module" src="https://unpkg.com/ionicons@5.5.2/dist/ionicons/ionicons.esm.js"></script>
<script src="https://developers.kakao.com/sdk/js/kakao.js"></script>

</head>
<body>
<%@include file="/WEB-INF/inc/top.jsp"%>
<div class="container">
<div class="login">
	<div class="text">
		<h2>로그인</h2>
		나만의 프로젝트를 발견해보세요 <br> 
	</div>
	<div class="login_form">
		<form name="loginForm" action="login_check.wow" method="post"> 
			<table class="table table-bordered">
			<tbody>
				<tr>
					<th><ion-icon name="person-circle" size="large"> </ion-icon></th>
					<th>아이디</th>
					<td><input type="text" name="userId" id="userId" class="form-control input-sm" value="" required="required"></td>
				</tr>
				<tr>
					<th><ion-icon name="key-outline" size="large"></ion-icon></th>
					<th>비밀번호</th>
					<td><input type="password" name="userPass" id="userPass" class="form-control input-sm" required="required"></td>
				</tr>
				<tr>
					<td colspan="3" class="loginmessage">
						<button type="submit" id="btnLogin" class="btn btn-primary">로그인</button>
					<c:if test="${param.message == 'idorpwnotcorrect' }">
                        <br><br>
                        <div style="color: red;">아이디 또는 비밀번호가 일치하지 않습니다.</div>
                    </c:if>
                    <c:if test="${param.message == 'idorpwempty' }">
                    	<br><br>
                        <div style="color: red;">아이디 또는 비밀번호에 값이 없습니다.</div>
                    </c:if>					
                    <c:if test="${param.message == 'joinsucess' }">
                    	<br><br>
                        <div style="color: red;">회원가입에 성공하였습니다.</div>
                    </c:if>			 
					</td>
				</tr>			
				<tr>
					<td colspan="3">
						<a href="<%=request.getContextPath()%>/join/join.wow">회원가입</a>
					</td>
				</tr>	
			</tbody>
			</table>
		</form>
	</div>
	</div>
</div>
</body>
</html>

로그인 실패 또는 회원가입 성공시

<c:if test="${param.message == 'idorpwnotcorrect' }">
    <br><br>
    <div style="color: red;">아이디 또는 비밀번호가 일치하지 않습니다.</div>
</c:if>
<c:if test="${param.message == 'idorpwempty' }">
    <br><br>
    <div style="color: red;">아이디 또는 비밀번호에 값이 없습니다.</div>
</c:if>					
<c:if test="${param.message == 'joinsucess' }">
    <br><br>
    <div style="color: red;">회원가입에 성공하였습니다.</div>
</c:if>

위의 코드와 같이 param.message을 사용해서 특정 메세지가 파라미터로 넘어오면 아래 글자가 뜨도록 구현하였다. 특정 메세지는 LoginController에서 아이디와 비밀번호를 체크한 다음 문제가 있어서 로그인을 하지 못하면 파라미터를 다시 돌려주도록 하였다.

3) LoginController

전체 코드는 아래 더보기를 눌러 확인해주세요.

더보기
package com.study.login.web;

import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.study.login.service.ILoginService;
import com.study.login.vo.UserVO;
import com.study.member.service.IMemberService;

@Controller
public class LoginController {
	
	@Inject
	ILoginService loginService;
	
	@Inject
	IMemberService memberService;
	
	@RequestMapping("/login/login.wow")
	public String login(HttpServletRequest req, HttpSession session) {	
		String msg = req.getParameter("message");
		if(msg == null) {
			session.setAttribute("PREPAGE", req.getHeader("referer"));
			return "/login/login";
		}else { //한 번 틀린 다음 로그인 시도시
			return "/login/login";
		}
	}
	
	@RequestMapping("/login/login_check.wow")
	public ModelAndView login_check(HttpServletRequest req, HttpSession session, ModelAndView mav) throws Exception {
 
		String id = req.getParameter("userId");
		String pw = req.getParameter("userPass");		

		if ((id == null || id.isEmpty()) || (pw == null || pw.isEmpty())) {
			mav.setViewName("redirect:/login/login.wow");
			mav.addObject("message", "idorpwempty");
			return mav;
		} else {
			UserVO user = loginService.getUser(id);
			if (user == null) { //아이디 틀렸을 때
				mav.setViewName("redirect:/login/login.wow");
				mav.addObject("message", "idorpwnotcorrect");
				return mav;
			} else //로그인 되었을 때
				if (user.getUserPass().equals(pw)) { 
					session.setAttribute("USER_INFO", user);
					String referer = (String) session.getAttribute("PREPAGE");
					if(referer!=null) {
						mav.setViewName("redirect:"+referer);
						return mav;
					}
					mav.setViewName("redirect:/funding/fundingList.wow");
					return mav;				
				} else { // 비번 틀렸을 때
					mav.setViewName("redirect:/login/login.wow");
					mav.addObject("message", "idorpwnotcorrect");
					return mav;
				}
			}
		
		}
	
	@RequestMapping("/login/logout.wow")
	public String logout(HttpSession session) {
			session.removeAttribute("USER_INFO");
			return "redirect:"+"/";  
	}
	

}

가) 로그인 화면 띄우기

@RequestMapping("/login/login.wow")
	public String login(HttpServletRequest req, HttpSession session) {	
		String msg = req.getParameter("message");
		if(msg == null) {
			session.setAttribute("PREPAGE", req.getHeader("referer"));
			return "/login/login";
		}else { //한 번 틀린 다음 로그인 시도시
			return "/login/login";
		}
	}

로그인 화면을 처음 들어 왔을 땐 바로 전 페이지를 PREPAGE에 저장해서 로그인 후 로그인 전에 보던 화면으로 넘어가게 설정한다. 그런데 이렇게하면 로그인에 실패했을 경우 그 다음 번에 로그인에 성공하였을 때 계속 실패 화면을 반복적으로 보여주는 문제가 있다. 이 때문에 로그인에 실패한 경우 메세지를 파라미터로 넘겨서 이 메세지가 있는 경우엔 referer를 저장하지 않도록 만들었다.

나) 아이디와 비밀번호 확인하기

if ((id == null || id.isEmpty()) || (pw == null || pw.isEmpty())) {
    mav.setViewName("redirect:/login/login.wow");
    mav.addObject("message", "idorpwempty");
    return mav;
} else {
    UserVO user = loginService.getUser(id);
    if (user == null) { //아이디 틀렸을 때
        mav.setViewName("redirect:/login/login.wow");
        mav.addObject("message", "idorpwnotcorrect");
        return mav;
} else //로그인 되었을 때
    if (user.getUserPass().equals(pw)) { 
        session.setAttribute("USER_INFO", user);
        String referer = (String) session.getAttribute("PREPAGE");
        if(referer!=null) {
            mav.setViewName("redirect:"+referer);
            return mav;
        }
        mav.setViewName("redirect:/funding/fundingList.wow");
        return mav;				
    } else { // 비번 틀렸을 때
        mav.setViewName("redirect:/login/login.wow");
        mav.addObject("message", "idorpwnotcorrect");
        return mav;
    }
}

ModelAndView를 사용해서 redirect 될 주소를 넣어 로그인 후 바로 해당 페이지로 이동하거나 로그인에 실패했을 경우 메세지를 담아서 다시 login페이지로 넘어가도록 구성하였다. 

다) 로그아웃

@RequestMapping("/login/logout.wow")
public String logout(HttpSession session) {
        session.removeAttribute("USER_INFO");
        return "redirect:"+"/";  
}

로그아웃시에는 session에 저장해두었던 USER_INFO를 제거하고 다시 홈 화면으로 돌아가게 하였다. 

댓글