웹 서버 개발 (17) 마이페이지
마이페이지
- 사용자 정보 확인 기능.
- 사용자 정보 변경 기능.
사용자 정보 확인
- 사용자는 아이디, 이메일, 주소를 확인할 수 있다.
- 마이페이지 버튼을 눌러 마이페이지에 접속하면 사용자 정보를 확인가능하다.
JSP 코드
main_page.jsp
- 마이페이지 버튼
<a class="button-design" href="/main_page/my_page">마이페이지</a>
- servlet 이 넘겨준 menuNumber을 이용하여 마이페이지를 불러온다.
<% if(menuNumber == 0) { %>
<jsp:include page="./sub_main/mypage.jsp" flush="false" />
<% } else if(menuNumber == 3) { %>
mypage.jsp
- servlet을 통해 db 에 저장된 사용자 정보를 받아온다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.mingyu2.login.authentication.database.User"%>
<%
var user = (User)request.getAttribute("user");
%>
<div style="border:1px solid #000000;margin:0 auto 0 auto; width: 60%;text-align: center;">
<h2>사용자 정보</h2>
<hr>
<span>아이디 : <b><%=user.getUsernameFilter() %></b></span><br>
<span>이메일 : <b><%=user.filter(user.getEmail()) %></b></span><br>
<span>우편번호 : <b><%=user.filter(user.getAddressNumber()) %></b></span><br>
<span>주소 : <b><%=user.filter(user.getAddress()) %></b></span><br>
<span>주소2 : <b><%=user.filter(user.getAddressSub()) %></b></span><br>
<a class="button-design" style="margin-top: 20px; margin-bottom:10px;" id="logout" href="/main_page/my_page/change_info">정보 수정</a>
</div>
Servlet 코드
MainPage.java
public class MainPage extends HttpServlet{
... 생략 ...
private boolean uriSearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
... 생략 ...
var myPage = "/main_page/my_page";
// 마이페이지
if(uri.equals(myPage)){
// 메뉴들
var menus = new ArrayList<Pair<String,Pair<String,Boolean>>>();
menus.add(new Pair<String,Pair<String,Boolean>>("Home",new Pair<String,Boolean>("/main_page",false)));
menus.add(new Pair<String,Pair<String,Boolean>>("게시판",new Pair<String,Boolean>(noticeBoard+baseNoticeBoardParameter(1,1,"","","",1), false)));
menus.add(new Pair<String,Pair<String,Boolean>>("버튼2",new Pair<String,Boolean>("",false)));
menus.add(new Pair<String,Pair<String,Boolean>>("버튼2",new Pair<String,Boolean>("",false)));
request.setAttribute("menus", menus);
return mainPage(request, response, 0);
}
사용자 정보 변경
- 사용자는 이메일, 주소, 비밀번호를 변경할 수 있다.
- 정보 수정 버튼을 눌러 정보 수정 페이지로 들어간다.
정보 변경
- email 과 주소를 변경한다.
정보 변경 SQL 문
update users
set email='이메일', 우편번호='우편번호', 주소='주소', 주소2='주소2'
where sid=1;
비밀번호 변경하기
- 비밀번호 변경은 중요한 요청이기 때문에 인증기능을 추가하였다.
- 즉 현재 비밀번호를 입력하고 일치하여야 비밀번호가 변경된다.
비밀번호 변경 SQL 문
update users
set salt="새로운 salt", password="해시화한 새로운 비번", modifi_time=변경시각
where sid=1 where sid=1;
JSP 코드
main_page.jsp
- servlet 에서 받은 menuNumber을 이용하여 사용자 정보 변경 페이지로 들어간다.
<% } else if(menuNumber == 3) { %>
<jsp:include page="./sub_main/mypage_change_info.jsp" flush="false" />
<% } else if(menuNumber == 1) { %>
mypage_change_info.jsp
- 사용자 정보를 수정하는 페이지이다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.mingyu2.login.authentication.database.User"%>
<%
var user = (User)request.getAttribute("user");
%>
<style>
.user-info-change > form > input {
font-size: 20px;
width: 100%;
}
</style>
<style>
.modal{
display: none;
position: fixed;
z-index: 1;
left: 0;
right: 0;
width: 100%;
height: 100%;
overflow: auto;
background-color: rgb(0, 0, 0);
background-color: rgba(0, 0,0, 0.4);
/* padding-top: 60px; */
}
.modal-content {
background-color: #fefefe;
margin: 5% auto 15% auto;
border: 3px solid;
width: 50%;
text-align: center;
}
#search-address {
width: 80%;
}
#search-address-bt {
width:20%;
}
.show-addresses {
height: 250px;
}
.over_ya {
overflow-y: auto;
}
.address-result {
width: 100%;
}
.address-result,.address-result th,.address-result td{
border: 1px solid #bcbcbc;
}
</style>
<script>
function search_address(){
let table = document.getElementById('address_table');
table.innerHTML = "";
let scount = document.getElementById('search_count');
scount.innerHTML = "<b>"+"</b>"
let input = document.getElementById('search-address').value;
if(input == ''){
return;
}
// 서버로 검색
const Http = new XMLHttpRequest();
const uri = "${signUpFindAddressNum}"+"?address="+input;
Http.open('GET', uri);
Http.send();
Http.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let re = Http.responseText;
username_is_success = re;
console.log(re);
// 정보 받음
if(re == ""){
return;
}
let split = re.split("\n");
let cnt = parseInt(split.length/3);
scount.innerHTML = "<b>"+cnt+"</b>"
console.log(cnt);
// 정보 테이블에 표시
// let table = document.getElementById('address_table');
for(let s = 0; s<cnt*3;s+=3){
table.innerHTML +=
"<tr>"+
"<th>"+split[s]+"</th>"+
"<td><a href='javascript:' onclick='select_address(this);'>"+split[s+1]+"</a><br><a href='javascript:' onclick='select_address(this);'>"+split[s+2]+"</a></td>"+
"</tr>";
}
}
};
}
function select_address(item){
let th = item.parentNode.parentNode.querySelector('th').innerHTML;
let tb = item.innerHTML;
document.getElementById('address-number').value = th;
document.getElementById('address-text').value = tb;
document.getElementById('addr').style.display='none';
address_is_success = "success";
let table = document.getElementById('address_table');
table.innerHTML = "";
document.getElementById('search-address').value = "";
let scount = document.getElementById('search_count');
scount.innerHTML = "<b>"+"</b>"
}
window.onclick = function(event) {
if(event.target == document.getElementById('addr')){
document.getElementById('addr').style.display = 'none';
let table = document.getElementById('address_table');
table.innerHTML = "";
document.getElementById('search-address').value = "";
let scount = document.getElementById('search_count');
scount.innerHTML = "<b>"+"</b>"
}
}
</script>
<div id="addr" class="modal">
<div class="modal-content">
<label>우편번호 검색</label><br>
<div>
<input id="search-address" type="text" required>
<a id="search-address-bt" href="javascript:search_address();">검색</a>
</div>
<hr>
<div style="text-align:left;">
<span><b>검색결과 : </b></span>
<span id="search_count" style="color:red;"></span>
<span><b> 건</b></span>
</div>
<div class="show-addresses over_ya">
<table class="address-result">
<thead>
<tr>
<th style="width:30%" scope="col">우편번호</th>
<th style="width:70%" scope="col">주소</th>
</tr>
</thead>
<tbody id="address_table">
</tbody>
</table>
</div>
<button type="button" onclick="document.getElementById('addr').style.display='none'">Cancel</button>
</div>
</div>
<div style="border:1px solid #000000;margin:0 auto 0 auto; width: 60%;text-align: center;">
<h2>사용자 정보 변경</h2>
<hr>
<div class="user-info-change" style="margin:0 auto 0 auto; width: 60%;text-align: left;">
<form action="change_user_info" method="POST">
<label>아이디</label><br>
<input value="<%=user.getUsernameFilter() %>" disabled><br><br>
<label>이메일</label><br>
<input name="email" value="<%=user.filter(user.getEmail()) %>"><br><br>
<label>주소</label><br>
<input id="address-number" name="address-number" value="<%=user.filter(user.getAddressNumber()) %>" readonly>
<input id="address-text" name="address" value="<%=user.filter(user.getAddress()) %>" readonly>
<input id="address-text2" name="address-sub" value="<%=user.filter(user.getAddressSub()) %>">
<button type="button" id="find_address_bt" onclick="document.getElementById('addr').style.display='block'">주소찾기</button><br><br>
<input type="submit" value="변경하기">
</form>
<br><hr><br>
<form action="change_user_pwd" method="POST">
<label>현재 비밀번호</label><br>
<input name="pwd" type="password">
<label>새로운 비밀번호</label><br>
<input name="new-pwd" type="password"><br><br>
<input type="submit" value="변경하기">
</form>
</div>
</div>
Servlet 코드
MainPage.java
- 주소와 이메일 변경을 DB 에 요청한다.
public class MainPage extends HttpServlet{
... 생략 ...
private boolean uriSearch(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
... 생략 ...
// 마이페이지 사용자 정보 변경 페이지
if(uri.equals(myPageChangeInfo)){
// 메뉴들
var menus = new ArrayList<Pair<String,Pair<String,Boolean>>>();
menus.add(new Pair<String,Pair<String,Boolean>>("Home",new Pair<String,Boolean>("/main_page",false)));
menus.add(new Pair<String,Pair<String,Boolean>>("게시판",new Pair<String,Boolean>(noticeBoard+baseNoticeBoardParameter(1,1,"","","",1), false)));
menus.add(new Pair<String,Pair<String,Boolean>>("버튼2",new Pair<String,Boolean>("",false)));
menus.add(new Pair<String,Pair<String,Boolean>>("버튼2",new Pair<String,Boolean>("",false)));
request.setAttribute("menus", menus);
request.setAttribute("signUpFindAddressNum", findAddress);
return mainPage(request, response, 3);
}
- 우편번호 찾기 요청을 처리한다.
// 우편번호 찾기
if(uri.equals(findAddress)){
var address = request.getParameter("address");
// 주소를 이용하여 우편 번호 찾기 시작!
var addressDAO = new AddressDAO(getServletContext());
var result = addressDAO.getAddressNumber(address);
// 끝
var sb = new StringBuilder();
sb.append(result);
var out = new BufferedWriter(new OutputStreamWriter(response.getOutputStream()));
out.write(sb.toString());
out.flush();
out.close();
return true;
}
- 사용자 정보 변경 요청을 처리한다.
if(request.getMethod().equals("POST") && uri.equals(changeUserInfo)){
var email = request.getParameter("email");
var addressNumber = request.getParameter("address-number");
var address = request.getParameter("address");
var addressSub = request.getParameter("address-sub");
var user = (User)request.getAttribute("user");
var isOK = new UsersDAO(getServletContext()).updateUserInfo(user.getSid(), email, addressNumber, address, addressSub);
System.out.println("요청옴 "+email+" "+addressNumber+" "+address+" "+addressSub+" "+ user.getSid());
var result = "";
if(isOK){
result = "<script>alert('change success!');location.href='"+myPage+"'</script>";
}else{
result = "<script>alert('change fail!');location.href='"+myPage+"'</script>";
}
simplePage(response, result);
return true;
}
- 비밀번호 변경 요청을 처리한다.
if(request.getMethod().equals("POST") && uri.equals(changePWD)){
var result = "";
var pwd = request.getParameter("pwd");
var newPwd = request.getParameter("new-pwd");
var user = (User)request.getAttribute("user");
var isOK = new UsersDAO(getServletContext()).updatePWD(user, pwd, newPwd);
System.out.println("비번 변경 요청 : "+pwd+" "+newPwd);
if(isOK){
result = "<script>alert('password change success!');location.href='/user-logout'</script>";
}else{
result = "<script>alert('password change fail!');location.href='/user-logout'</script>";
}
simplePage(response, result);
return true;
}
UsersDAO.java
- DB에 저장된 주소 및 이메일을 실질적으로 변경해준다.
// update user info
public boolean updateUserInfo(long sid,String email, String addressNumber, String address, String addressSub){
var regexPattern = "^(?=.{1,64}@)[A-Za-z0-9_-]+(\\.[A-Za-z0-9_-]+)*@"+"[^-][A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$";
if(!email.matches(regexPattern) || addressNumber.equals("") || address.equals("")){
return false;
}
if(addressSub.equals("")){
addressSub = " "; // 빈칸으로 db 업데이할 때 오류 발생 방지.
}
var re = false;
var query = new StringBuilder();
query.append("update ");
query.append(tableName);
query.append(" set email=?, 우편번호=?, modifi_time=?, 주소=?, 주소2=? where sid=?");
try {
connectDB();
var pstmt = conn.prepareStatement(query.toString());
pstmt.setString(1, email);
pstmt.setString(2, addressNumber);
pstmt.setLong(3, System.currentTimeMillis());
pstmt.setString(4, address);
pstmt.setString(5, addressSub);
pstmt.setLong(6, sid);
pstmt.executeUpdate();
re = true;
} catch (Exception e) {
e.printStackTrace();
re = false;
} finally {
Close();
}
return re;
}
- DB에 저장된 비밀번호를 실질적으로 변경해준다.
public class UsersDAO {
... 생략 ...
// update user password
public boolean updatePWD(User user,String pwd, String newPwd){
var re = false;
if(pwd.equals("") || newPwd.equals("")){
return false;
}
// 현재 비밀번호 일치하는지 확인
var info = LoginAuthentication.userAuthenticatoin(context, user.getUsername(), pwd);
if(info == null){
return false;
}
// 비밀번호 변경하기
try {
// salt 만들기
var random = SecureRandom.getInstanceStrong();
var bytes = new byte[16];
random.nextBytes(bytes);
var salt = new String(Base64.getEncoder().encode(bytes));
// 새로운 비번 sha-512 로 해시 암호화 하기
var md = MessageDigest.getInstance("SHA-512");
md.update(salt.getBytes());
md.update(newPwd.getBytes());
var password = String.format("%064x",new BigInteger(1,md.digest()));
var query = new StringBuilder();
query.append("update ");
query.append(tableName);
query.append(" set salt=?, password=?, modifi_time=? where sid=?");
connectDB();
var pstmt = conn.prepareStatement(query.toString());
pstmt.setString(1, salt);
pstmt.setString(2, password);
pstmt.setLong(3, System.currentTimeMillis());
pstmt.setLong(4, user.getSid());
pstmt.executeUpdate();
re = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
Close();
}
return re;
}
결론
- 마이페이지를 만들어 db에 저장된 사용자의 정보를 보여주었다. 그리고 사용자의 정보를 업데이트할 수 있는 기능도 추가하였다.
- 이메일, 주소, 비밀번호를 마이페이지에서 변경할 수 있다.
댓글남기기