Spring

Spring STEP 13 - Board

2023. 6. 21. 16:09
728x90

★ 프로젝트 생성

- New > Spring Legacy Project > Spirng MVC Project > SecurityBoardTest > com.test.board > Finish

 

■ 구현 목표

  • 1. 회원 기능(DB 구축, 가입 X, 로그인 구현)
  • 2. 게시판 기능(CRUD)

 

■ 기초 셋팅

  • https://github.com/pinnpublic/class/wiki/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-%EC%9D%BC%EA%B4%84-%EC%A0%81%EC%9A%A9
 

스프링 프로젝트 일괄 적용

수업. Contribute to pinnpublic/class development by creating an account on GitHub.

github.com

  • ojdbc6.jar 파일 가져오기 -> configure.buildpath -> external add -> Deploy -> add
  • pom.xml 의존 4개 추가
<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-web</artifactId>
   <version>5.0.7.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-config</artifactId>
   <version>5.0.7.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-core</artifactId>
   <version>5.0.7.RELEASE</version>
</dependency>

<dependency>
   <groupId>org.springframework.security</groupId>
   <artifactId>spring-security-taglibs</artifactId>
   <version>5.0.7.RELEASE</version>
</dependency>

 

■ xml 생성

- WEB-INF/spring/"security-context.xml" 생성
  • namespace -> security 추가
  • 코드작성
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:security="http://www.springframework.org/schema/security"
	xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
		http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

	<security:http>
		<security:form-login/>
	</security:http>
	
	<security:authentication-manager>
	</security:authentication-manager>

</beans>

 

■ web.xml 셋팅

<param-value>
    /WEB-INF/spring/root-context.xml
    /WEB-INF/spring/security-context.xml
</param-value>

<filter>
   <filter-name>springSecurityFilterChain</filter-name>
   <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>

<filter-mapping>
   <filter-name>springSecurityFilterChain</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

 

★ 구현

1. 회원 인증(로그인, 로그아웃)
2. 게시판
  • DB  설계
create table tblMember2 (
    id varchar2(30) not null primary key,
    name varchar2(30) not null,
    pw varchar2(30) not null,
    email varchar2(100) not null,
    gender char(1) not null,
    regdate date default sysdate not null,
    enabled char(1) default '1'
);

create table tblAuth (
    id varchar2(30) not null references tblMember2(id),
    auth varchar2(50) not null
);
  • 파일 생성
com.test.security > CustomUserDetailsService.java

com.test.domain > CustomUser.java
                > MemberDTO.java
                > AuthDTO.java
  • MemberDTO.java -> 코드 작성
@Data
public class MemberDTO {
	
	private String id;
	private String pw;
	private String name;
	private String email;
	private String regdate;
	private String enabled;
    private String gender;
	
	private List<AuthDTO> authlist;
	
}
  • AuthDTO.java -> 코드 작성
@Data
public class AuthDTO {

	private String id;
	private String auth;
	
}
  • CustomUser -> 코드 작성
@Getter
public class CustomUser extends User {

		private MemberDTO member;

		public CustomUser(String username, String password
	            , Collection<? extends GrantedAuthority> authorities) {
	      super(username, password, authorities);
	   }
	   
	   public CustomUser(MemberDTO dto) {
		   
		   //MemberDTO > Customer(User)
	      
	      super(dto.getId(), dto.getPw(), dto.getAuthlist().stream().map(auth -> new SimpleGrantedAuthority(auth.getAuth())).collect(Collectors.toList()));
	      
	      this.member = dto;
	   }
}
  • CustomUserDetailsService -> 코드 작성
public class CustomUserDetailsService implements UserDetailsService {

	@Autowired
	private MemberMapper mapper;
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		
		//기본 > username, password, enabled, authority
		//재정의 > 기본 + 추가 정보
	
		MemberDTO dto = mapper.read(username);
		
		return dto != null ? new CustomUser(dto) : null ;
	}
	
}
  • src/main/resources > com > test > mapper > MemberMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.test.mapper.MemberMapper">

</mapper>
  • MemberTest.java -> 회원 추가
package com.test.security;

import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml", "file:src/main/webapp/WEB-INF/spring/security-context.xml"})
public class MemberTest {

	@Autowired
	private DataSource ds;
	
	@Autowired
	private PasswordEncoder encoder;
	
	@Test
	public void testInsertMember() {
		
		String sql = "insert into tblMember2(id, pw, name, email, gender) values (?, ?, ?, ?, ?)";
		
		try {
			
			Connection conn = ds.getConnection();
			PreparedStatement stat = conn.prepareStatement(sql);
			
			stat.setString(1, "dog");
			stat.setString(2, encoder.encode("1111"));
			stat.setString(3, "강아지");
			stat.setString(4, "dog@gmail.com");
			stat.setString(5, "m");
			
			stat.executeUpdate();
			
			stat.setString(1, "cat");
			stat.setString(2, encoder.encode("1111"));
			stat.setString(3, "고양이");
			stat.setString(4, "cat@gmail.com");
			stat.setString(5, "f");
			
			stat.executeUpdate();
			
			stat.setString(1, "dong");
			stat.setString(2, encoder.encode("1111"));
			stat.setString(3, "동재");
			stat.setString(4, "dong@gmail.com");
			stat.setString(5, "f");
			
			stat.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}
  • MemberTest2 -> 권한 추가
package com.test.security;

import java.sql.Connection;
import java.sql.PreparedStatement;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"file:src/main/webapp/WEB-INF/spring/root-context.xml", "file:src/main/webapp/WEB-INF/spring/security-context.xml"})
public class MemberTest2 {

	@Autowired
	private DataSource ds;
	
	@Autowired
	private PasswordEncoder encoder;
	
	@Test
	public void testInsertMember() {
		
		String sql = "insert into tbl_member_auth(id, auth) values (?, ?)";
		
		try {
			
			Connection conn = ds.getConnection();
			PreparedStatement stat = conn.prepareStatement(sql);
			
			stat.setString(1, "dog");
			stat.setString(2, "ROLE_MEMBER");
			
			stat.executeUpdate();
			
			stat.setString(1, "cat");
			stat.setString(2, "ROLE_MEMBER");
			
			stat.executeUpdate();
			
			stat.setString(1, "dong");
			stat.setString(2, "ROLE_MEMBER");
			
			stat.executeUpdate();
			
			stat.setString(1, "dong");
			stat.setString(2, "ROLE_ADMIN");
			
			stat.executeUpdate();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
}
  • MemberMapper.xml -> 코드 작성
<mapper namespace="com.test.mapper.MemberMapper">

	<resultMap type="com.test.domain.MemberDTO" id="mMap">
		<id property="id" column="id" />
		<result property="id" column="id" />
		<result property="pw" column="pw" />
		<result property="name" column="name" />
		<result property="email" column="email" />
		<result property="gender" column="gender" />
		<result property="regdate" column="regdate" />
		<result property="enabled" column="enabled" />
		<collection property="authlist" resultMap="aMap"></collection>
	</resultMap>
	
	<resultMap type="com.test.domain.AuthDTO" id="aMap">
		<result property="id" column="id" />
		<result property="auth" column="auth" />
	</resultMap>
	
	<select id="read" resultType="">
	
		select 
		    m.id, pw, name, email, gender, regdate, enabled, auth
		from tblMember2 m
		    left outer join tblAuth a
		        on m.id = a.id
		            where m.id = #{id}
	
	</select>

</mapper>
  • security-context.xml -> 추가
<security:http>
    <!-- 로그인 -->
    <security:form-login login-page="/customlogin.do"/>
    <!-- 로그아웃 -->
    <security:logout logout-url="/customLogout.do" invalidate-session="true" logout-success-url="/index.do"/>
</security:http>

 

★ 파일 생성

- com.test.controller > CommonController.java
                      > MemberController.java
                      > BoardController.java
                    
- views > template.jsp
		> index.jsp
        
- views > member > login.jsp
                 > logout.jsp

- views > board > list.jsp
                > view.jsp
                > add.jsp
                > edit.jsp
                > del.jsp
                
- views > "inc" > header.jsp

 

★ 작업

  • servlet-context.xml -> 스캔 추가
<context:component-scan base-package="com.test.controller" />
  • CommonController.java -> 코드 추가
@Controller
public class CommonController {
	
	@GetMapping("/template.do")
	public String template() {
		
		return "template";
	}
	
	@GetMapping("/index.do")
	public String index() {
		
		return "index";
	}
}
  • MemberController.java -> 코드 추가
@Controller
public class MemberController {
	
	@GetMapping("/member/login.do")
	public String login() {
		
		return "member/login";
	}
	
	@GetMapping("/member/logout.do")
	public String logout() {
		
		return "member/logout";
	}
}

 

■ jsp 작성

  • header.jsp
<header>
	<h1>Spring Security</h1>
	<ul>
		<li><a href="/index.do">HOME</a>
		<li class="divider"></li>
		<li><a href="/member/login.do">LOGIN</a>
		<li><a href="/member/logout.do">LOGOUT</a>
		<li class="divider"></li>
		<li><a href="/board/list.do">BOARD</a>
	</ul>
</header>
  • index.jsp
<!-- index.jsp -->
<%@ include file="/WEB-INF/views/inc/header.jsp" %>

<h2>시작 페이지 <small>index</small></h2>
  • login.jsp
<!-- login.jsp -->
<%@ include file="/WEB-INF/views/inc/header.jsp" %>

<h2>Member <small>Login</small></h2>

<form method="post" action="login">
<table>
    <tr>
        <th>아이디</th>
        <td><input type="text" name="username" required></td>
    </tr>
    <tr>
        <th>암호</th>
        <td><input type="password" name="password" required></td>
    </tr>
</table>
<div>
    <button type="submit" class="in">로그인</button>
</div>
</form>
728x90
저작자표시 비영리 변경금지 (새창열림)

'Spring' 카테고리의 다른 글

Spring STEP 14 - RESTful Service  (0) 2023.06.22
Spring STEP 13 - Board 2  (0) 2023.06.22
Spring STEP 12 - Spring Security 2  (0) 2023.06.21
Spring STEP 11 - Spring Security  (0) 2023.06.20
Spring STEP 10 - MyBatisSimple  (0) 2023.06.19
'Spring' 카테고리의 다른 글
  • Spring STEP 14 - RESTful Service
  • Spring STEP 13 - Board 2
  • Spring STEP 12 - Spring Security 2
  • Spring STEP 11 - Spring Security
IT의 큰손
IT의 큰손
IT계의 큰손이 되고 싶은 개린이의 Log 일지
IT의 큰손
Developer Story House
IT의 큰손
전체
오늘
어제
  • 분류 전체보기 (457)
    • 정보처리기사 필기 (18)
    • 정보처리기사 실기 (12)
    • 정보처리기사 통합 QUIZ (12)
    • 빅데이터 (11)
    • 안드로이드 (11)
    • 웹페이지 (108)
    • 자바 (49)
    • SQLD (3)
    • 백준 알고리즘 (76)
    • 데이터베이스 (41)
    • 깃허브 (2)
    • Library (14)
    • Server (31)
    • 크롤링&스크래핑 (3)
    • Spring (23)
    • Vue.js (13)
    • React (27)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

  • Developer Stroy House

인기 글

태그

  • React
  • IT개발자
  • 개발블로그
  • 정보처리기사
  • 정보처리기사필기
  • DBA
  • ajax
  • 코딩테스트
  • 앱개발자
  • 웹페이지
  • html
  • 백엔드
  • 웹개발
  • java
  • it
  • 알고리즘
  • 프론트엔드
  • IT자격증
  • jsp
  • 자바
  • jquery
  • css
  • 정보보안전문가
  • 백준
  • IT자격증공부
  • JavaScript
  • 웹개발자
  • DB
  • 개발자
  • 데이터베이스

최근 댓글

최근 글

Designed By hELLO
IT의 큰손
Spring STEP 13 - Board
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.