DeseoDeSeo
[Spring Boot] Spring Boot Security 본문
SpringMVC10 복사 붙여넣기 해서 SpringMVC11로 이름 바꿈
pom.xml
-> pom.xml 체크
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
finish 누르면 이렇게 2개 추가됨.
그리고 아래 작성해서 추가해줌.
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-taglibs</artifactId>
</dependency>
list.jsp
https://www.w3schools.com/bootstrap4/bootstrap_cards.asp
BS4 Cards > Header and Footer 부분 가져오기
https://www.w3schools.com/bootstrap4/bootstrap_jumbotron.asp
Jumbotron > Full-width Jumbotron 부분 가져오기
kr.spring,entity > class생성 'Member'
package kr.spring.entity;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.Id;
import lombok.Data;
import lombok.ToString;
@Entity
@Data
@ToString
public class Member {
@Id
private String username; //spring Security에서는 id가 아닌 username로 지정함.
private String password; //spring Security에서는 pw가 아닌 password로 지정함.
@Enumerated(EnumType.STRING) //@Enumerated -> 열거형(권한이 여러개임)
private Role role; // 권한
// ----------------여기까지는 반드시 필수로 넣어줘야한다.
private String name; //이름
private boolean ebled; // 계정활성화, 비활성화 부분
}
kr.spring.emtity > enum생성 'Role'
package kr.spring.entity;
public enum Role {
ADMIN, MANAGER, MEMBER;
}
kr,spring.entity > class생성 ''CustomUser"
package kr.spring.entity;
import java.util.Collection;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
public class CustomUser extends User{
private Member member;
public CustomUser(Member member) {
super(member.getUsername(), member.getPassword(), AuthorityUtils.createAuthorityList("ROLE_"+member.getRole().toString()));
this.member = member;
}
// 우리가 만든 회원정보 -> Member
//Spring Context holder에 저장하기 위해서는
//User형태로 변환하여서 넣어줘야한다.
//그걸 해주는 클래스가 바로 CustomUser 클래스임.
}
kr.spring > 패키지 생성 'kr.spring.config'
kr,spring.repository > interface 생성 'MemberRepository'
package kr.spring.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Service;
import kr.spring.entity.Member;
public interface MemberRepository extends JpaRepository<Member, String>{
}
kr.spring.config > class생성 ' SecurityConfiguration '
package kr.spring.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
@Configuration //환경설정 파일 설정
public class SecurityConfiguration {
@Autowired
private UserDetailsServiceImpl userService;
@Bean
public PasswordEncoder passwordEncoder() { //비밀번호 인코딩 기능
return PasswordEncoderFactories.createDelegatingPasswordEncoder();
}
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
http.csrf().disable(); //csrf토큰 비활성화
http.authorizeHttpRequests() //사용자의 요청을 핸들링
.antMatchers("/","/member/**").permitAll() // "/", "member"하위에 모든 접근을 허용하겠다.
.antMatchers("/board/**").authenticated() // board로 접근하는 모든 경우는 인증된(로그인한) 사용자만 허용됨.
.and() //추가
.formLogin() //우리가 만든 별도의 로그인 폼을 사용하겠다.
.loginPage("/member/login")//로그인 페이지는 member안에 login에서 하겠다.
.defaultSuccessUrl("/board/list") //로그인 성공시 board list로 이동하겠다.
.and() // 추가
.logout()
.logoutUrl("/member/logout") // 로그아웃 실행하고 싶다면 member/logout으로 요청하겠다.
.logoutSuccessUrl("/"); //로그아웃하고 /로 이동하겠다.
http.userDetailsService(userService);
return http.build();
}
}
src > webapp > web-inf > jsp생성 ' index.jsp '
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix ="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix ="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<c:set var="cpath" value="${pageContext.request.contextPath}" />
<!DOCTYPE html>
<html lang="en">
<head>
<title>Bootstrap Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/css/bootstrap.min.css">
<script src="https://cdn.jsdelivr.net/npm/jquery@3.6.4/dist/jquery.slim.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/popper.js@1.16.1/dist/umd/popper.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.6.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
<div class="card" style=" width:600px; text-align:center; margin:0px auto;">
<div class="jumbotron jumbotron-fluid">
<div class="container">
<h1>Spring Boot</h1>
<p>Main page</p>
</div>
</div>
<div class="card-body">
<p class="card-text" style="text-align:left;">메뉴를 선택하세요.</p>
<div class="card-group">
<div class="card bg-warning">
<div class="card-body text-center">
<p class="card-text">글 목록 보기</p>
</div>
</div>
<div class="card bg-danger">
<div class="card-body text-center">
<p class="card-text">로그인</p>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
kr.spring.controller > class생성 ' HomeController.java'
package kr.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class HomeController {
@RequestMapping("/")
public String index() {
return"index";
}
}
이제 실행할 때 ,localhost:8081/boot해야됨.
web-inf > folder 생성 'member' > jsp 생성 ' login '
kr.spring.controller > controller생성 ' Membercontroller.java '
package kr.spring.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/member/*")
public class MemberController {
@GetMapping("/login")
public String login() {
return "member/login";
}
}
BoardServiceImpl.java
//상세보기
@Override
public Board get(Long idx) {
Optional<Board> vo = boardRepository.findById(idx); //board형태가 아니라 optional형태임.
return vo.get(); //이렇게 하면 optional안에 있는걸 꺼내주는거임.
}
optional : 원하는 값이 있으면 원하는 객체로 받고 없으면 Exceptional 처리를 하는 패턴임.
( NPE, NullPointerException)
list.jsp
$(document).ready(function(){
var regForm=$("#regForm");
$("button").on("click",function(){//버튼의 모든 클릭을 감지하겠다.
var oper = $(this).data("oper");
if(oper=="register"){
regForm.submit();
}else if(oper=="reset"){
regForm[0].reset();
}else if(oper=="list"){
location.href="${cpath}/list";
} else if(oper=="remove"){
var idx = regForm.find("#idx").val();
location.href="${cpath}/remove?idx="+idx;
} else if(oper=="updateForm"){
regForm.find("#title").attr("readonly",false);
regForm.find("#content").attr("readonly",false);
var upBtn="<button onclick='goUpdate()' class='btn btn-sm btn-info' type='button'>수정완료</button>";
$("#update").html(upBtn);
}
});
location.href = " 이동할 페이지 주소 "
게시글 삭제하기
list.jsp
<input type="hidden" id="idx" name="idx" value="">
idx값을 hidden으로 숨기고
function printBoard(vo){
var regForm = $("#regForm");
regForm.find("#title").val(vo.title);//title을 찾아서 value을 넣을 것이다
regForm.find("#content").val(vo.content);//title을 찾아서 value을 넣을 것이다
regForm.find("#writer").val(vo.writer);//title을 찾아서 value을 넣을 것이다
regForm.find("input").attr("readonly", true);
regForm.find("textarea").attr("readonly", true);
//상세보기를 누르면 목록,수정,삭제가 나옴.
$("#regDiv").css("display", "none");
$("#updateDiv").css("display", "block");
regForm.find("#idx").val(vo.idx);
}
regForm.find("#idx").val(vo.idx);
: 게시글 불러올 때, input의 idx를 찾아서 idx값을 넣어준다.
else if(oper=="remove"){
var idx = regForm.find("#idx").val();
location.href="${cpath}/remove?idx="+idx;
}
이렇게 하면 클릭할 때마다 url뒤에 idx값이 넘어간다.
BoardService.java
public void delete(Long idx);
BoardServiceImpl.java
@Override
public void delete(Long idx) {
boardRepository.deleteById(idx);
}
게시판 수정하기
list. jsp
<div id="updateDiv" style="display: none;">
<button class="btn btn-sm btn-primary" data-oper="list" type="button">목록</button>
<span id="update">
<button class="btn btn-sm btn-warning" data-oper="updateForm" type="button">수정</button>
</span>
<button class="btn btn-sm btn-success" data-oper="remove" type="button">삭제</button>
</div>
수정 하고 나서 수정완료 버튼으로 바꿔주기 위해서 span태그로 감싼다.
else if(oper=="updateForm"){
regForm.find("#title").attr("readonly",false);
regForm.find("#content").attr("readonly",false);
var upBtn="<button onclick='goUpdate()' class='btn btn-sm btn-info' type='button'>수정완료</button>";
$("#update").html(upBtn);
}
readonly속성 풀어주고 새로운 버튼을 추가한다.
버튼을 누르면 update가 작동한다.
function goUpdate(){
var regForm =$("#regForm");
regForm.attr("action","${cpath}/modify");
regForm.submit();
}
BoardService.java
public void update(Board vo);
BoardServiceImpl.java
@Override
public void update(Board vo) {
//JPA의 SAVE메서드는 새로운pk값 또는 없는 값이 들어오면 insert기능을
// 기존에 존재하는 pk값이 들어오면 update기능을 함.
boardRepository.save(vo);
}
'spring > Spring Boot' 카테고리의 다른 글
[Spring Boot ] 로그인 구현 (0) | 2023.10.23 |
---|---|
ミ★ Spring boot 02 (1) | 2023.10.20 |
ミ★ Spring Boot 01 (0) | 2023.10.16 |