JSP

회원 가입 로그인 성공 실패

승모근뭉치 2022. 12. 17. 22:06

day31 프로젝트 내 WebContent 내 join.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>회원가입</title>
</head>
<body><!-- 중복확인버튼이 잘 안될때 자바스크립트가 로딩이 잘 안될땐 쿠키를 지워주면 반영이 잘된다 -->
	<form action="join_db.jsp" method="post" name="joinForm">
		<!-- 폼에 이름을 joinForm 붙이면 form은 하나의 객체가 되어 나중에 가져올때 편하다 -->
		<p>
			<label>아이디 : <input type="text" name="id" id="id"></label>
			<input type="button" onclick="checkId()" value="중복 확인">
		</p>
		<p id="result"></p>
		<p>
			<label>이름 : <input type="text" name="name"></label>
		</p>
		<p>
			<label>비밀번호 : <input type="password" name="password">
		</p>
		<p>
			<label>비밀번호 확인 : <input type="password" name="password_re">
		</p>
		<p>
			성별 : 남자 <input type="radio" name="gender" value="남자" checked>
			여자 <input type="radio" name="gender" value="여자" checked>
		</p>
		<p>
			<label>
				우편번호 : 
				<input type="text" name="zipcode" class="postcodify_postcode5" value="" />
				<button type="button" id="postcodify_search_button">검색</button><br /> 
			</label>
		</p>
		<p>
			<label>
				주소 : 
				<input type="text" name="address" class="postcodify_address" value="" /><br /> 
			</label>
		</p>
		<p>
			<label>
				상세 주소 : 
				<input type="text" name="address_detail" class="postcodify_details" value="" /><br />
			</label>
		</p>
		<p>
			<label>
				참고 항목 : 
				 <input type="text" name="address_etc" class="postcodify_extra_info" value="" /><br />
			</label><!-- label에 클릭하면 뒤 인풋박스에 포커스가 간다 -->
		</p>
		<input type="button" onclick="join()" value="회원가입 완료">
	</form>
</body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="//d1p7wdleee1q2z.cloudfront.net/post/search.min.js"></script>
<script> $(function() { $("#postcodify_search_button").postcodifyPopUp(); }); </script>
<script src="member.js"></script>
</html>

 

day31 프로젝트 내 WebContent 내 member.js

/**
 * 회원가입 유효성 검사
 */

var form = document.joinForm;

function join(){
	//value를 조건식 안에서 사용하면
	//값이 있을 때 true, 값이 없을 때 false
	if(!form.id.value){
		alert("아이디를 입력해주세요");
		form.id.focus();
		return;
	}
	if(form.id.value.length < 4 || form.id.value.length > 16){
		alert("아이디는 4자 이상, 16자 이하로 입력해주세요.");
		form.id.focus();
		return;
	}
	if(!form.name.value){
		alert("이름을 입력해주세요.");
		form.name.focus();
		return;
	}
	if(!form.password.value){
		alert("비밀번호를 입력해주세요.");
		form.password.focus();
		return;
	}
	
	//8자리 이상, 대문자, 소문자, 숫자, 특수문자 모두 포함되어 있는 지 검사
	let reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$/;
	let hangleCheck = /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/;
	
	if(!reg.test(form.password.value)){
		alert("비밀번호는 8자리 이상이어야 하며, 대문자/소문자/숫자/특수문자 모두 포함해야 합니다.");
		form.password.focus();
		return;
	}
	
	//같은 문자를 4번 사용할 수 없다.
	if(/(\w)\1\1\1/.test(form.password.value)){
		alert("같은 문자를 4번 이상 사용하실 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호 안에 아이디가 있을 때
	if(form.password.value.search(form.id.value) != -1){
		alert("비밀번호에 아이디를 포함할 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호에 한글이 있으면 안된다.
	if(hangleCheck.test(form.password.value)) {
		alert("비밀번호에 한글을 사용할 수 없습니다.");
		form.password.focus();
		return;
	}
	
	//비밀번호에 공백을 포함할 수 없다.
	if(form.password.value.search(/\s/) != -1){
		alert("비밀번호에 공백 없이 입력해주세요.");
		form.password.focus();
		return;
	}
	
	if(form.password.value != form.password_re.value) {
		alert("비밀번호를 확인해주세요");
		form.password.focus();
		return;
	}
	
	if(!form.id.readOnly){
		alert("아이디 중복 검사를 진행해주세요.");
		return;
	}
	form.submit();
}

$("input[name='id']").on("click", function(){
	form.id.readOnly = false;
})

function checkId(){
	var xhr = new XMLHttpRequest();
	
	xhr.open("GET", "join_ok.jsp?id=" + document.getElementById("id").value, true);
	xhr.send();
	
	xhr.onreadystatechange = function(){
		if(xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200){
			//console.log(xhr.responseText);
			document.getElementById("result").innerHTML = xhr.responseText.trim();
			if(xhr.responseText.search("가능") != -1){
				form.id.readOnly = true;
			}
		}
	}
}

day 31 프로젝트 내 WebContent 내 join_ok.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean class="dao.UserDAO" id="dao"/>
<%
	if(dao.checkId(request.getParameter("id"))){
		out.println("중복된 아이디입니다.");
	}else{
		out.println("사용 가능한 아이디입니다.");
		//out.println 위와 요 바로 위 둘 중 하나는 member.js에서
		//console.log(xhr.responseText); responseText로 받을것이다.
	}
%>

day31 프로젝트 내 src 내 dao패키지 내 UserDAO.java

package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import vo.UserVO;

//private int num;
//private String id;
//private String name;
//private String password;
//private String gender;
//private String zipcode;
//private String address;
//private String address_detail;
//private String address_etc;

public class UserDAO {
	
	Connection conn; //외부 저장소인 DBMS를 드라이버를 통해 객체로 가져온 연결 객체
	PreparedStatement pstm; //문자열안에 있는 SQL문을 객체로 저장, 변수가 들어갈 자리에 알맞는 값을 넣어줌, SQL문 실행시킨
	ResultSet rs; //SELECT의 결과를 담는 객체
	
	public void join(UserVO user) {
		//SQL문 작성
		String query = "INSERT INTO TBL_USER VALUES(SEQ_USER.NEXTVAL, ?, ?, ?, ?, ?, ?, ?, ?)";
		
		try {
			//connection객체를 전달받는다.
			conn = DBConnecter.getconnection();
			//위에서 작성한 쿼리문을 prepareStatement에 전달한다.
			pstm =conn.prepareStatement(query);
			//?자리에 알맞는 변수를 전달해준다.
			pstm.setString(1, user.getId());
			pstm.setString(2, user.getName());
			pstm.setString(3, user.getPassword());
			pstm.setString(4, user.getGender());
			pstm.setString(5, user.getZipcode());
			pstm.setString(6, user.getAddress());
			pstm.setString(7, user.getAddress_detail());
			pstm.setString(8, user.getAddress_etc());
			
			//DML중 INSERT 쿼리를 실행하는 메소드를 사용한다.
			pstm.executeUpdate();//실행된건수를반환 결과 건수
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(pstm != null) {
					pstm.close();
				}
				if(conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
		}
	}
	
	//아이디 중복검사
	public boolean checkId(String id) {
		String query = "SELECT COUNT(ID) FROM TBL_USER WHERE ID = ?";
		boolean check = false;
		try {
			//DBMS 연결 객체 가져오기
			conn = DBConnecter.getconnection();
			//String으로 선언된 쿼리를 pstm객체에 전달하기
			pstm = conn.prepareStatement(query);
			//SQL 쿼리에 ?가 있다면 알맞는값으로 지정해주기
			pstm.setString(1, id);
			//쿼리 실행 후 결과를 rs객체에 담기
			rs = pstm.executeQuery();
			
			rs.next();//행가져오기
			//위에서 가져온 행의 열을 타입에 맞춰서 가져오기
			check = rs.getInt(1) == 1;	//0일때 중복 없음(false),1일때 중복 있음(true)
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs != null){
					rs.close();
				}
				if(pstm != null) {
					pstm.close();
				}
				if(conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);//자원사용후닫을때도 쿼리문을 쓰므로 오류발생하면 어플리케이션이 종료되게한다
			}
		}
		
		return check;
	}
	
	public boolean login(String id, String pw) {
		//login_ok.jsp가 서블릿이다.jsp는 컴파일하면 jspservlet이 된다.
		String query = "SELECT COUNT(ID) FROM TBL_USER WHERE ID = ? AND PASSWORD = ?";
		boolean check = false;
		conn = DBConnecter.getconnection();
		try {
			pstm = conn.prepareStatement(query);
			pstm.setString(1, id);
			pstm.setString(2, pw);
			
			rs = pstm.executeQuery();
			rs.next();//행갖고오기
			check = rs.getInt(1) == 1;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(rs != null) {
					rs.close();
				}
				if(pstm != null) {
					pstm.close();
				}
				if(conn != null) {
					conn.close();
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				throw new RuntimeException(e);
			}
		}
		return check;
	}
	
}

day31 프로젝트 내 src 내 dao 패키지 내 DBConnecter.java

package dao;
//C:\app\ydbon\product\11.2.0\dbhome_1\jdbc\lib 여기서 ojdbc6 jar추가
//위의 빌드 패스는 자바 쪽이고 WAS라는친구는 WebContent밑의web-INF밑에 LIB를
//참조탐색하므로 이 폴더는 웹쪽이다.요쪽에도 JDBC을 넣어줘야 한다.요렇게 빌드패스하나
//lib폴더 하나한쌍을 이루어야한다.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnecter {
	//DAO에서 모든 메소드에 필요한 DB연결 문법을 미리 메소드에 선언해 놓는다.
	public static Connection getconnection() {//사용하기편하기위해STATIC을붙여준다
		Connection conn = null;
		
		try {
			//DB연결을 위한 정보를 입력한다(url, username, password).
			String url = "jdbc:oracle:thin:@localhost:1521:orcl";
			String user = "hr";
			String pw ="hr";
			
			//드라이버를 메모리에 할당한다.
			//메모리에 드라이버를 올리는 부분 따옴표안의클래스를 메모리에 올린다.
			Class.forName("oracle.jdbc.driver.OracleDriver");
			
			//입력한 정보를 전달하여 드라이버를 통해 연결 객체를 가져온다.
			conn = DriverManager.getConnection(url, user, pw);
			
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return conn;
	}
}

day31프로젝트 내 WebContent 내 join_db.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%request.setCharacterEncoding("UTF-8"); %>
<jsp:useBean class="dao.UserDAO" id="dao"/>
<jsp:useBean class="vo.UserVO" id="vo"/>
<jsp:setProperty property="*" name="vo"/>

<%
	dao.join(vo);
	response.sendRedirect("login.jsp");
	//System.out.println(vo.getName());
%>

day31프로젝트 내 src 내 vo 패키지 내 UserVO.java

package vo;

//NUM NUMBER PRIMARY KEY,
//ID VARCHAR2(1000),
//NAME VARCHAR2(1000),
//PASSWORD VARCHAR2(1000),
//GENDER VARCHAR2(100),
//ZIPCODE VARCHAR2(100),
//ADDRESS VARCHAR2(1000),
//ADDRESS_DETAIL VARCHAR2(1000),
//ADDRESS_ETC VARCHAR2(1000)

//그리드(편집)모드 : ALT + SHIFT + A (SHIFT를 누른상태에서 방향키를 위아래로)
//커서는 shift를 누른 후 방향키 위 아래로 늘리기
public class UserVO {
	
	private int num;
	private String id;
	private String name;
	private String password;
	private String gender;
	private String zipcode;
	private String address;
	private String address_detail;
	private String address_etc;
	
	public UserVO() {
		// TODO Auto-generated constructor stub
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getZipcode() {
		return zipcode;
	}

	public void setZipcode(String zipcode) {
		this.zipcode = zipcode;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getAddress_detail() {
		return address_detail;
	}

	public void setAddress_detail(String address_detail) {
		this.address_detail = address_detail;
	}

	public String getAddress_etc() {
		return address_etc;
	}

	public void setAddress_etc(String address_etc) {
		this.address_etc = address_etc;
	}
}

day31프로젝트 내 WebContent내 login.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<input type="hidden" name="type" id="type" value="<%=request.getParameter("type") %>">
	<form action="login_ok.jsp" name="loginForm" method="post"><!-- 1차적으로 비밀번호안보이게 post -->
		<p>
			<label>
				아이디 : <input type="text" name="id">
			</label>
		</p>
		<p>
			<label>
				비밀번호 : <input type="password" name="password">
			</label>
		</p>
		<p>
			<input type="button" value="로그인" onclick="login()">
		</p>
	</form>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.2/rollups/aes.js"></script>
<script>
	if(document.getElementById("type").value == "false"){
		alert("로그인 실패");
	}

	function login(){
		var form = document.loginForm;
		if(!form.id.value){
			alert("아이디를 입력해주세요.");
			return
		}
		if(!form.password.value){
			alert("비밀번호를 입력해주세요.");
			return;
		}
		
		form.password.value = btoa(form.password.value);
		
		form.submit();
	}
</script>
</html>

day31프로젝트 내 WebContent 내 login_ok.jsp

<%@page import="java.util.Base64"%>
<%@page import="java.util.Base64.Decoder"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:useBean class="dao.UserDAO" id="dao"/>
<%
	String id = request.getParameter("id");
	String pw = request.getParameter("password");
	
	Decoder decoder = Base64.getDecoder();
	//패스워드 원본,그래야지만 디비에 고대로 들어가기때문에 디비에서검사가 된다.
	pw = new String(decoder.decode(pw));//여기서 바이트로 리턴하므로 스트링 생성자에 바이트를전달하면 문자열로 바뀐다.
	
	//HttpSession session = request.getSession();
	if(dao.login(id, pw)){
		session.setAttribute("id", id);//서버에저장된다.
		response.sendRedirect("login_success.jsp");
	}else{
		response.sendRedirect("login.jsp?type=false");
	}
	
%>

day31프로젝트 내 WebContent 내 login_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>로그인 성공</title>
</head>
<body>
	<h1>
	<%=session.getAttribute("id") %>님 환영합니다!
	</h1>
	<input type="button" onclick="goLogout()" value="로그아웃">
</body>
<script>
	function goLogout(){
		location.href="logout.jsp";
	}
</script>
</html>

day31프로젝트 내 WebContent 내 logout.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	session.invalidate();	//세션 전체 삭제
	//session.removeAttribute("id"); //특정 세션 값 삭제
%>
<script>
	location.href="login.jsp";
</script>