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>