이제 로그인 로그아웃 문제는 어떻게 정리를 했다.
컨테이너를 도입하면서 로그인 한 유저 정보를 더 쉽게 가져올 수 있게 되어서 기존의 코드와 다르게 보완했다.
package org.koreait.controller;
import org.koreait.container.Container;
import org.koreait.dto.Member;
import org.koreait.service.MemberService;
public class MemberController {
MemberService memberService;
public MemberController() {
this.memberService = Container.memberService;
}
public void doJoin() {
String loginId = null;
String loginPw = null;
String loginPwConfirm = null;
String name = null;
System.out.println("==회원가입==");
while (true) {
System.out.print("로그인 아이디 : ");
loginId = Container.sc.nextLine().trim();
if (loginId.isEmpty() || loginId.contains(" ")) {
System.out.println("아이디 똑바로 써");
continue;
}
boolean isLoindIdDup = memberService.isLoginIdDup(loginId);
if (isLoindIdDup) {
System.out.println(loginId + "는(은) 이미 사용중");
continue;
}
break;
}
while (true) {
System.out.print("비밀번호 : ");
loginPw = Container.sc.nextLine().trim();
if (loginPw.isEmpty() || loginPw.contains(" ")) {
System.out.println("비번 똑바로 입력해");
continue;
}
boolean loginPwCheck = true;
while (true) {
System.out.print("비밀번호 확인 : ");
loginPwConfirm = Container.sc.nextLine().trim();
if (loginPwConfirm.isEmpty() || loginPwConfirm.contains(" ")) {
System.out.println("비번 확인 똑바로 써");
continue;
}
if (!loginPw.equals(loginPwConfirm)) {
System.out.println("일치하지 않아");
loginPwCheck = false;
}
break;
}
if (loginPwCheck) {
break;
}
}
while (true) {
System.out.print("이름 : ");
name = Container.sc.nextLine();
if (name.isEmpty() || name.contains(" ")) {
System.out.println("이름 똑바로 써");
continue;
}
break;
}
int id = memberService.doJoin(loginId, loginPw, name);
System.out.println(id + "번 회원이 생성되었습니다");
}
public void doLogin() {
if (Container.session.loginedMemberId != -1) {
System.out.println("이미 로그인 되어있음.");
return;
}
String loginId = null;
String loginPw = null;
System.out.println("==로그인==");
while (true) {
System.out.print("로그인 아이디 : ");
loginId = Container.sc.nextLine().trim();
if (loginId.length() == 0 || loginId.contains(" ")) {
System.out.println("아이디 똑바로 써");
continue;
}
boolean isLoindIdDup = memberService.isLoginIdDup(loginId);
if (isLoindIdDup == false) {
System.out.println(loginId + "는(은) 없어");
continue;
}
break;
}
Member member = memberService.getMemberByLoginId(loginId);
int tryMaxCount = 3;
int tryCount = 0;
while (true) {
if (tryCount >= tryMaxCount) {
System.out.println("비번 다시 확인하고 시도해");
break;
}
System.out.print("비밀번호 : ");
loginPw = Container.sc.nextLine().trim();
if (loginPw.isEmpty() || loginPw.contains(" ")) {
tryCount++;
System.out.println("비번 똑바로 입력해");
continue;
}
if (!member.getLoginPw().equals(loginPw)) {
tryCount++;
System.out.println("일치하지 않아");
continue;
}
Container.session.loginedMember = member;
Container.session.loginedMemberId = member.getId();
System.out.println(member.getName() + "님 환영합니다");
break;
}
}
public void doLogout() {
if(Container.session.loginedMember != null) {
System.out.println("== 로그 아웃 완료 ==");
Container.session.loginedMemberId = -1;
Container.session.loginedMember = null;
}else System.out.println("로그인 부터 해.");
}
public void showMemberProfile() {
if (Container.session.loginedMember == null) {
System.out.println("로그인 되어있지 않음.");
} else {
System.out.println("번호 : " + Container.session.loginedMember.getId());
System.out.println("아이디 : " + Container.session.loginedMember.getLoginId());
System.out.println("이름 : " + Container.session.loginedMember.getName());
System.out.println("가입 날짜 : " + Container.session.loginedMember.getRegDate());
System.out.println("회원정보 수정 날짜 : " + Container.session.loginedMember.getUpdateDate());
}
}
}
로그인 할 때 Member Class를 도입해서 Map에 해당 유저 정보를 저장하고 회원 정보 상세보기 기능까지 만들었다. 이러면 수업 때 안풀렸던 article 의 권한 확인과 글쓰기시 작성자의 정보까지 저장할 수 있게 된다. article DB에 memberId 칼럼을 추가했고, article Class에는 name을 도입해 자연스레 list와 detail에 호환되게끔 만들어서 delete와 modify만 손보면 된다. 아마 사실상 delete만 해결되면 될텐데 여기서 유저와 글을 검증하는 쿼리를 찾는데 약간 애를 먹었다.
시도하던 쿼리는 이런 형태였는데
public boolean canAccess() {
SecSql sql = new SecSql();
sql.append("SELECT a.*, m.id FROM article a");
sql.append("INNER JOIN `member` m");
sql.append("ON a.memberId = m.id");
sql.append("WHERE a.id = ?;", Container.session.loginedMember.getId());
return DBUtil.selectRowBooleanValue(Container.conn, sql);
}
}
이게 mysql에서는 잘보이지만 java는 무슨 소리인지 알아듣지 못했다. 그래서 수업때 들었던 것을 잘 생각해 보니, <,> 로 boolean 값을 가져올 수 있게 만들고, WHERE문에 AND를 더해서 글의 id와 유저의 id를 대조할 수 있게까지 만들어서 내가 검색한 글 1개만 뽑아올 수 있게끔 했다. 뭐가 하나라도 일치하지 않으면 값이 오지 않을테니 아마 잘 작동하지 않을까 싶다. 아래가 해당 쿼리.
public boolean canAccess(int articleId) {
SecSql sql = new SecSql();
sql.append("SELECT COUNT(*) > 0"); // 권한이 있는지 확인하는 부울 값을 반환하기 위해 COUNT 사용
sql.append("FROM article a");
sql.append("INNER JOIN `member` m ON a.memberId = m.id");
sql.append("WHERE a.id = ?", articleId);
sql.append("AND m.id = ?", Container.session.loginedMember.getId());
return DBUtil.selectRowBooleanValue(Container.conn, sql);
}
}
그리고 article controller의 코드는,
public void doDelete(String cmd) {
if(Container.session.loginedMember == null){
System.out.println("로그인 안되어 있어.");
return;
}
int id = 0;
try {
id = Integer.parseInt(cmd.split(" ")[2]);
} catch (Exception e) {
System.out.println("번호는 정수로 입력해");
return;
}
boolean canAccess = articleService.canAccess(id);
int deleteId = articleService.isExistId(id);
if(canAccess){
if (deleteId == 0) {
System.out.println(id + "번 게시물 없어.");
} else {
articleService.doDelete(id);
System.out.println(id + "번 글이 삭제되었습니다.");
}
} else System.out.println("삭제 권한 없어.");
}
이렇게 만들었다. 추가로 로그인 되어있지 않을 때는 아예 접근하지 못하게 했다.
생각한 대로 잘 된다! 새로 아이디를 생성해서 글을 쓰고 검증 해도 잘 된다. 그런데 약간 수정해야될 게 보였는데 "id번 게시물이 없어" 문구가 아예 작동되지 않을 환경에 놓여져서 저 글을 밖으로 빼서 return시켰다.
if (deleteId == 0) {
System.out.println(id + "번 게시물 없어.");
return;
}
if(canAccess){
articleService.doDelete(id);
System.out.println(id + "번 글이 삭제되었습니다.");
} else System.out.println("삭제 권한 없어.");
}
이렇게.
이제 modify만 하면 된다. 아마 순식간에 하지 않을까 싶다. 토대는 다 만들었고 만든 메서드 넣고 제대로 작동하는지만 확인하면 되니까.
public void doModify(String cmd) {
int id = 0;
try {
id = Integer.parseInt(cmd.split(" ")[2]);
} catch (Exception e) {
System.out.println("번호는 정수로 입력해");
return;
}
int articleId = articleService.isExistId(id);
if (articleId == 0) {
System.out.println(id + "번 게시물 없어.");
} else {
System.out.println("==수정==");
System.out.print("새 제목 : ");
String newTitle = Container.sc.nextLine().trim();
System.out.print("새 내용 : ");
String newBody = Container.sc.nextLine().trim();
articleService.doUpdate(newTitle, newBody, id);
System.out.println(id + "번 글이 수정되었습니다.");
}
}
이런 모양에서,
public void doModify(String cmd) {
if(Container.session.loginedMember == null){
System.out.println("로그인 안되어 있어.");
return;
}
int id = 0;
try {
id = Integer.parseInt(cmd.split(" ")[2]);
} catch (Exception e) {
System.out.println("번호는 정수로 입력해");
return;
}
boolean canAccess = articleService.canAccess(id);
int articleId = articleService.isExistId(id);
if (articleId == 0) {
System.out.println(id + "번 게시물 없어.");
return;
}
if (canAccess) {
System.out.println("==수정==");
System.out.print("새 제목 : ");
String newTitle = Container.sc.nextLine().trim();
System.out.print("새 내용 : ");
String newBody = Container.sc.nextLine().trim();
articleService.doUpdate(newTitle, newBody, id);
System.out.println(id + "번 글이 수정되었습니다.");
}
}
이렇게 바꿨고, 실행해 보면..
아.. 생각해보니까 쿼리도 고쳐야된다.
일단 기존 쿼리는
public void doUpdate(String newTitle, String newBody, int id) {
SecSql sql = new SecSql();
sql.append("UPDATE article");
sql.append("SET updateDate = NOW(),");
if (!newTitle.isEmpty()) {
sql.append("title = ?,", newTitle);
}
if (!newBody.isEmpty()) {
sql.append("`body`= ?", newBody);
}
sql.append("WHERE id = ?;", id);
DBUtil.update(Container.conn, sql);
}
와 이건 좀 고치기 힘들겠는데.. 일단 해보자.
일단 기존 쿼리문 참고해서
UPDATE article a
INNER JOIN `member` m
SET a.updateDate = NOW(),
a.title = '2222',
a.`body`= '2222'
WHERE a.id = 1 AND m.id = 1;
이렇게 수정하니까 잘 된다. 그럼 바로 우리 JDBC에 적용시켜보자.
public void doUpdate(String newTitle, String newBody, int id) {
SecSql sql = new SecSql();
sql.append("UPDATE article a");
sql.append("INNER JOIN `member` m");
sql.append("SET a.updateDate = NOW(),");
if (!newTitle.isEmpty()) {
sql.append("a.title = ?,", newTitle);
}
if (!newBody.isEmpty()) {
sql.append("a.`body`= ?", newBody);
}
sql.append("WHERE a.id = ?", id);
sql.append("AND m.id = ?;", Container.session.loginedMember.getId());
DBUtil.update(Container.conn, sql);
}
오케이 수정까지 잘 된다 수정 시간까지 잘 바뀐다.
명령어 > article modify 6
==수정==
새 제목 : sksk
새 내용 : sksk
6번 글이 수정되었습니다.
명령어 > article detail 6
번호 : 6
제목 : sksk
내용 : sksk
작성자 : 김철수
작성시간 : 2024-07-15 18:31:29
수정시간 : 2024-07-15 19:18:01
근데 문제가 하나 있다면 수정 권한이 없다는 출력문이 왜 안뜨지??
아 내가 코드를 안썼구나.
오케이 문제 다 해결.
이게 뭐가 하나가 풀리면 쭉 풀리는데 그 하나를 푸는게 참 어려운 것 같다. 아무튼 오늘은 여기까지.
초복이니까 삼계탕 먹으러 갈거다..
'Coding History' 카테고리의 다른 글
2024. 07. 16 코파일럿(이하 AI)에 관한 고찰 (0) | 2024.07.16 |
---|---|
국비 지원 IT(웹앱개발) 취업반 강의 29일차 (DB, JDBC) (0) | 2024.07.16 |
국비 지원 IT(웹앱개발) 취업반 강의 28일차 (DB, JDBC) (0) | 2024.07.15 |
2024. 07. 14. JDBC 리팩토링 (0) | 2024.07.14 |
JDBC 회원 기능 추가중 (1) | 2024.07.12 |