스프링 부트 - 회원가입 /시큐리티 로그인 하기

공현지·2023년 4월 18일
0

spring

목록 보기
27/30
post-thumbnail

회원가입

<%@ 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="f" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>Insert title here</title>
<style type="text/css">
*, *:before, *:after {
	box-sizing: border-box;
	margin: 0;
	padding: 0;
}

body {
	font-family: 'Open Sans', Helvetica, Arial, sans-serif;
	background: #ededed;
}

input, button {
	border: none;
	outline: none;
	background: none;
	font-family: 'Open Sans', Helvetica, Arial, sans-serif;
}

$
contW: 900px ;
 $imgW: 260px ;
 $formW: $contW - $imgW ;
 $switchAT: 1.2s ;

 $inputW: 260px ;
 $btnH: 36px ;

 $diffRatio: ( $contW - $imgW) / $contW ;

 @mixin signUpActive { .cont .s--signup & { @content;
	
}

}
.tip {
	font-size: 20px;
	margin: 40px auto 50px;
	text-align: center;
}

.cont {
	overflow: hidden;
	position: relative;
	width: $contW;
	height: 550px;
	margin: 0 auto 100px;
	background: #fff;
}

.form {
	position: relative;
	width: $formW;
	height: 100%;
	transition: transform$switchAT ease-in-out;
	padding: 50px 30px 0;
}

.sub-cont {
	overflow: hidden;
	position: absolute;
	left: $formW;
	top: 0;
	width: $contW;
	height: 100%;
	padding-left: $imgW;
	background: #fff;
	transition: transform$switchAT ease-in-out;
	@
	include
	signUpActive
	{
	transform
	:
	translate3d(
	$
	formW
	*
	 
	-1
	,
	0
	,
	0
	);
}

}
button {
	display: block;
	margin: 0 auto;
	width: $inputW;
	height: $btnH;
	border-radius: 30px;
	color: #fff;
	font-size: 15px;
	cursor: pointer;
}

.img {
	overflow: hidden;
	z-index: 2;
	position: absolute;
	left: 0;
	top: 0;
	width: $imgW;
	height: 100%;
	padding-top: 360px; &: before { content : '';
	position: absolute;
	right: 0;
	top: 0;
	width: $contW;
	height: 100%;
	background-image:
		url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/142996/sections-3.jpg');
	background-size: cover;
	transition: transform$switchAT ease-in-out;
}

&
:after {
	content: '';
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	background: rgba(0, 0, 0, 0.6);
}

@
include signUpActive { &:before { transform:translate3d( $formW, 0, 0);
	
}

}
&
__text {
	z-index: 2;
	position: absolute;
	left: 0;
	top: 50px;
	width: 100%;
	padding: 0 20px;
	text-align: center;
	color: #fff;
	transition: transform$switchAT ease-in-out; h2 { margin-bottom : 10px;
	font-weight: normal;
}

p {
	font-size: 14px;
	line-height: 1.5;
}

&
.m--up { @include signUpActive { transform:translateX( $imgW *2);
	
}

}
&
.m--in {
	transform: translateX($ imgW * -2);
	@
	include
	signUpActive
	{
	transform
	:
	translateX(
	0
	);
}

}
}
&
__btn {
	overflow: hidden;
	z-index: 2;
	position: relative;
	width: 100px;
	height: $btnH;
	margin: 0 auto;
	background: transparent;
	color: #fff;
	text-transform: uppercase;
	font-size: 15px;
	cursor: pointer; &: after { content : '';
	z-index: 2;
	position: absolute;
	left: 0;
	top: 0;
	width: 100%;
	height: 100%;
	border: 2px solid #fff;
	border-radius: 30px;
}

span {
	position: absolute;
	left: 0;
	top: 0;
	display: flex;
	justify-content: center;
	align-items: center;
	width: 100%;
	height: 100%;
	transition: transform$switchAT;
	&.
	m--in
	{
	transform
	:
	translateY(
	$
	btnH
	*
	-2
	);
	@
	include
	signUpActive
	{
	transform
	:
	translateY(
	0
	);
}

}
&
.m--up { @include signUpActive { transform:translateY( $btnH *2);
	
}

}
}
}
}
h2 {
	width: 100%;
	font-size: 26px;
	text-align: center;
}

label {
	display: block;
	width: $inputW;
	margin: 25px auto 0;
	text-align: center; span { font-size : 12px;
	color: #cfcfcf;
	text-transform: uppercase;
}

}
input {
	display: block;
	width: 100%;
	margin-top: 5px;
	padding-bottom: 5px;
	font-size: 16px;
	border-bottom: 1px solid rgba(0, 0, 0, 0.4);
	text-align: center;
}

.forgot-pass {
	margin-top: 15px;
	text-align: center;
	font-size: 12px;
	color: #cfcfcf;
}

.submit {
	margin-top: 40px;
	margin-bottom: 20px;
	background: #d4af7a;
	text-transform: uppercase;
}

.fb-btn {
	border: 2px solid #d4af7a;
	color: #d4af7a; span { font-weight : bold;
	color: darken(#768cb6, 20%);
}

}
.sign-in {
	transition-timing-function: ease-out; @ include signUpActive {
	transition-timing-function : ease-in-out;
	transition-duration: $switchAT;
	transform: translate3d($ formW, 0, 0);
}

}
.sign-up {
	transform: translate3d($ contW * -1, 0, 0);
	@
	include
	signUpActive
	{
	transform
	:
	translate3d(
	0
	,
	0
	,
	0
	);
}

}
.icon-link {
	position: absolute;
	left: 5px;
	bottom: 5px;
	width: 32px; img { width : 100%;
	vertical-align: top;
}
&
--twitter
{
left
:
auto;
right
:
5px;
}
}
</style>
</head>
<body>


	<h2>회원가입</h2>
	<form action="/signup" method="post" id="regForm">

		<div class="form sign-in" >
			<div class="input-box" >
				<label for="name">*아이디</label>
				<input type="text" id="username" name="username" 
					placeholder="*아이디" oninput="noSpaceForm(this);"  />
			   <!--중복체크 -->
			     <span id="idCheckMsg"></span>
			</div>
			
			<div class="input-box">
		    	 <label for="e">이메일</label>
				<input type="email" id="email" name="email" placeholder="*exam@exam.com"  oninput="noSpaceForm2(this);" > 
			  <!--중복체크 -->
			     <span id="emailCheckMsg"></span>
			</div>			

			<div class="input-box">
			<label for="pW">비밀번호</label>
	
					
					<input type="password"
					id="userPw" name="password" maxlength='4' 
					placeholder="*비밀번호 숫자 4자리 " onkeyup="noSpaceForm(this);"
					oninput="this.value = this.value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');">
				
					<p style="color: red">숫자 4자리만 입력가능</p>
			</div>

			<div class="input-box">
			    <label for="ppw">비밀번호</label>
				<input type="password" id="userPwChk" name="Confirm" maxlength='4' 
					placeholder="*비밀번호 확인 " onkeyup="noSpaceForm(this);"  class=" passConfirm()"
					oninput="this.value = this.value.replace(/[^0-9]/g, '').replace(/(\..*)\./g, '$1');">
                <font id="chkNotice" size="2"></font>
			</div>

		</div>



		<button class="submit" id="btn_join" type="submit">회원가입</button>
	<button class="submit" id="btn_list" type="button">처음으로</button>
	</form>


</body>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">


	//첫 글자 공백만 사용 못 하게
/* 	function noSpaceForm(obj) {
		if (obj.value == " ") // 공백 체크
		{
			//alert("해당 항목에는 공백을 사용할 수 없습니다.\n\n공백 제거됩니다.");
			obj.focus();
			obj.value = obj.value.replace(' ', ''); // 공백 제거
			return false;
		}
	} */
	// 공백 사용 못 하게
	function noSpaceForm(obj) {
	    var pattern = /\s/g;  // 정규표현식 패턴으로 공백 문자 전체 체크
	    if (pattern.test(obj.value)) {
	        //alert("해당 항목에는 공백을 사용할 수 없습니다.\n\n공백 제거됩니다.");
	        obj.focus();
	        obj.value = obj.value.replace(pattern, '');  // 공백 제거
	       
	    }
	}
	
	function noSpaceForm2(obj) {
	    var emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/; // 이메일 주소 형식 체크
	    var value = obj.value.replace(/\s/g, ''); // 공백 제거
	    if (!emailPattern.test(value)) {
	        obj.value = value;
	    }
	}

	

	//공백체크
$('#memberpage').on('click','#btn_join', function(){ 
	//$("#btn_join").click(function() {
		// 이메일 검사 정규식
		var mailJ = /^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$/i;

		if ($('#username').val().trim() == '') {
			alert("username을 입력해주세요")
			$('#username').focus();
			return false;
		}else if ($('#email').val().trim() == '') {
			alert("email를 입력해주세요")
			$('#email').focus();
			return false;
			// 이메일 정규식
			if (mailJ.test($('#email').val())){
				
				inval_Arr[2] = true;
			} else {
				inval_Arr[2] = false;
			}
			
		}else if ($('#userPw').val().trim() == '') {
			alert("password를 입력해주세요")
			$('#userPw').focus();
			return false;
		}
		 else if ($('#userPwChk').val().trim() == '') {
			alert("password 확인 입력해주세요")
			$('#userPwChk').focus();
	      	
			return false;
		}else if ($('#userPw').val() != $('#userPwChk').val()){
			alert("비밀번호가 일치하지 않습니다.다시 확인해주세요")		
			return false;
					
		}else if($('#userPw').val() == $('#userPwChk').val()){
			alert("회원가입되었습니다")
		
			return true;
		}
		


	})

	//아이디 중복확인 체크
	function  checkIdDuplication() {
		if ($("#username").val().length > 0) {
			$.ajax({
				url : "/idChk",
				type : "post",
				dataType : "json",
				data : {
					"username" : $("#username").val()
				},
				success : function(data) {
					if (data == 1) {
						 $('#idCheckMsg').html('<span style="color:green;">중복된 아이디입니다.</span>');
						//alert("중복된 아이디입니다.")
						$('#username').focus();
						return false;
					} else if (data == 0) {
						$('#idCheckMsg').html('<span style="color:red;">사용가능한 아이디입니다.</span>');
						//alert("사용가능한 아이디입니다.")
						$('#email').focus();
						return false;
					}
				}
			});
		} else {
			//alert("username을 입력해주세요")
			$('#username').focus();
			  return false;
		}
	}
	
	$(function() {
		  // 아이디 중복 체크를 수행하는 함수를 호출하는 이벤트 핸들러 등록
		  $('#username').on('blur', checkIdDuplication);
		});
	

	
	//이메일 중복확인 체크
	function  checkEmailDuplication() {
		if ($("#email").val().length > 0) {
			$.ajax({
				url : "/emailChk",
				type : "post",
				dataType : "json",
				data : {
					"email" : $("#email").val()
				},
				success : function(data) {
					if (data == 1) {
						$('#emailCheckMsg').html('<span style="color:green;">중복된 이메일 입니다.</span>');
						$('#email').focus()
						
						return false;
					} else if (data == 0) {
						$('#emailCheckMsg').html('<span style="color:red;">사용가능한 이메일 입니다.</span>');
				
						$('#password').focus()
						return false;
					}
				}
			});
		} 
	}
	$(function() {
		  // 아이디 중복 체크를 수행하는 함수를 호출하는 이벤트 핸들러 등록
		  $('#email').on('blur', checkEmailDuplication);
		});
	

	//처음으로 버튼
	$('#memberpage').on('click','#btn_list', function(){ 
		window.location.href = '/index'

	})
	

	//비밀번호 확인 
	$(function(){
	    $('#userPw').keyup(function(){
	      $('#chkNotice').html('');
	    });

	    $('#userPwChk').keyup(function(){

	        if($('#userPw').val() != $('#userPwChk').val()){
	          $('#chkNotice').html('비밀번호 일치하지 않음<br><br>');
	          $('#chkNotice').attr('color', '#f82a2aa3');
	        } else{
	          $('#chkNotice').html('비밀번호 일치함<br><br>');
	          $('#chkNotice').attr('color', '#199894b3');
	        }

	    });
	});
	
</script>

</html>

회원가입,아이디 중복체크 userController

@RequiredArgsConstructor
@Controller
public class UserController {
	private final UserService us;
	private final BCryptPasswordEncoder passwordEncoder;

	// 회원가입
	@RequestMapping(value = "signup", method = RequestMethod.POST)
	public String signup(Member member) { // 회원 가입
		// 비밀번호 암호화
		String encodedPassword = passwordEncoder.encode(member.getPassword());
		// 암호화 비번 다시 board에 넣음
		member.setPassword(encodedPassword);
		int result = us.insertmember(member);

		return "redirect:/index";

	}

	// 아이디 중복체크
	@ResponseBody
	@RequestMapping(value = "/idChk", method = RequestMethod.POST)
	public int idChk(Member member) throws Exception {
		int result = us.idChk(member);

		return result;

	}

	
}

회원가입,아이디 중복체크 userServicelmpl

@RequiredArgsConstructor
@Service
public class UserServicelmpl implements UserService {

		//Mybatis DB 연동
		private final UserDao ud;
		
		@Override
		public int insertmember(Member member) {
			int result=0;
			result=ud.insertMember(member);
			
			return result;
		}

		@Override
		public int idChk(Member member) {
			int result = ud.idChk(member);			
			
			return result;
		}
}

회원가입,아이디 중복체크 userDaolmpl


@RequiredArgsConstructor
@Repository
public class UserDaolmpl implements UserDao {

	//Mybatis DB 연동
	private final SqlSession session;
			
	@Override
	public int insertMember(Member member) {
		int result =0;
		try {
			result=session.insert("Memberinsert",member );
		} catch (Exception e) {
			System.out.println("다오오류"+e.getMessage());
			e.printStackTrace();
		}
		return result;
	}

	@Override
	public int idChk(Member member) {
		int result = session.selectOne("memberidChk", member);
		
		return result;
	}



회원가입,아이디 중복체크 user.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.oracle.proj.dto.userMapper">

<insert id="Memberinsert" parameterType="member">
 insert into member ( 
                      username 
					 ,email
                     ,password
                     ,role
                     
                                
                      )
            values (
                      #{username}
                     ,#{email}
                     ,#{password}
                     ,'ROLE_USER'
                   )
</insert>

<select id="memberidChk" resultType="int" >
    SELECT COUNT(*) FROM MEMBER
	WHERE username = #{username}

</select>

</mapper>

스프링부트 그레들 시큐리티 로그인

bulid.gradle

여기에 먼저 추가해준다

// Spring Security 추가
	implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'com.navercorp.lucy:lucy-xss:1.6.3'
    implementation 'org.apache.commons:commons-text:1.9'

MemberDetails

package com.oracle.prj.auth;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service;

import com.oracle.prj.Dto.Member;

import lombok.RequiredArgsConstructor;


public class MemberDetails implements UserDetails {
	// member 패키지에 선언해놓은 member 엔티티를 사용하기 위해 선언
    private final Member dto;

    public MemberDetails(Member dto) {
        this.dto = dto;
    }

    //생성자
    public Member getDto(){
        return dto;
    }
	
    // member 계정의 권한을 담아두기위해
	@Override
	public Collection<? extends GrantedAuthority> getAuthorities() {
		  List<GrantedAuthority> authorities = new ArrayList<>();
	        authorities.add(new SimpleGrantedAuthority(dto.getRole()));
	        return authorities;
	}

    // member 계정의 비밀번호를 담아두기 위해
	@Override
	public String getPassword() {
		 return dto.getPassword();
	}
    // member 계정의 아이디를 담아두기 위해
	@Override
	public String getUsername() {
		return dto.getUsername();
    }
	 // 계정이 만료되지 않았는지를 담아두기 위해 (true: 만료안됨)
	@Override
	public boolean isAccountNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}
	   // 계정이 잠겨있지 않았는지를 담아두기 위해 (true: 잠기지 않음)
	@Override
	public boolean isAccountNonLocked() {
		// TODO Auto-generated method stub
		return true;
	}
    // 계정의 비밀번호가 만료되지 않았는지를 담아두기 위해 (true: 만료안됨)
	@Override
	public boolean isCredentialsNonExpired() {
		// TODO Auto-generated method stub
		return true;
	}
    // 계정이 활성화되어있는지를 담아두기 위해 (true: 활성화됨)
	@Override
	public boolean isEnabled() {
		// TODO Auto-generated method stub
		return true;
	}

}

MemberDetailservice

package com.oracle.prj.auth;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import com.oracle.prj.Dao.UserDao;
import com.oracle.prj.Dto.Member;

import lombok.RequiredArgsConstructor;

@Service
@RequiredArgsConstructor
public class MemberDetailservice implements UserDetailsService {

	private final UserDao ud;
	
	
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
		// 넘겨받은 id 로 DB 에서 회원 정보를 찾음
        Member dto = ud.findByLoginId(username);
        // 없을경우 에러 발생
        if(dto == null)
        	throw new UsernameNotFoundException("아이디 혹은 비밀번호가 틀렸습니다");
        // MemberDetailsImpl 에 Member 객체를 넘겨줌
        return new MemberDetails(dto);
	}

}

userdaolmpl

@Override
	public Member findByLoginId(String username) {
		 Member dto = null;
		 try {
			dto=session.selectOne("findByLoginId",username);
			 
		} catch (Exception e) {
			System.out.println("다오오류"+e.getMessage());
			e.printStackTrace();
		}
		return dto;
	}

user.xml

<select id="findByLoginId" parameterType="String" resultType="Member">
		select username
		      ,password 
		      ,role
		      ,email
		from member
		where username =#{username} 
</select>

CustomAuthenticationProvider

package com.oracle.prj.auth;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {

	   @Autowired
	    private MemberDetailservice memberDetailService;
	
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		String username = authentication.getName(); // 사용자가 입력한 id
        String passwd = (String) authentication.getCredentials(); // 사용자가 입력한 password

        // 생성해둔 memberDetailService 에서 loadUserByUsername 메소드를 호출하여 사용자 정보를 가져온다.
        MemberDetails details = (MemberDetails) memberDetailService.loadUserByUsername(username);

        // ====================================== 비밀번호 비교 ======================================
        // 사용자가 입력한 password 와 DB 에 저장된 password 를 비교한다.

        // db 에 저장된 password
        String dbPassword = details.getPassword();
        // 암호화 방식 (BCryptPasswordEncoder) 를 사용하여 비밀번호를 비교한다.
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

        if(!passwordEncoder.matches(passwd, dbPassword)) {
            //System.out.println("[사용자] 비밀번호가 일치하지 않습니다.");
            throw new BadCredentialsException("[사용자] 아이디 또는 비밀번호가 일치하지 않습니다.");
        }
        return new UsernamePasswordAuthenticationToken(details, null, details.getAuthorities());
	}

	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return authentication.equals(UsernamePasswordAuthenticationToken.class);
    }

}

MemberAuthSuccessHandler(성공시)

package com.oracle.prj.auth;

import java.io.IOException;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

public class MemberAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{

	 @Override
	    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException {
		   
		 //로그인한 username가져가기위해서 해줌 
		 HttpSession session = request.getSession();
		 session.setAttribute("username", authentication.getName() );
	        
		 // 로그인 성공시 이동할 페이지
		 setDefaultTargetUrl("/index");
		 // 로그인 성공시 이동할 페이지로 이동
		 super.onAuthenticationSuccess(request, response, authentication);

	 }
}


MemberAuthFailureHandler(실패시)

package com.oracle.prj.auth;

import java.io.IOException;

import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationSuccessHandler;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;

public class MemberAuthSuccessHandler extends SimpleUrlAuthenticationSuccessHandler{

	 @Override
	    public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication ) throws IOException, ServletException {
		   
		 //로그인한 username가져가기위해서 해줌 
		 HttpSession session = request.getSession();
		 session.setAttribute("username", authentication.getName() );
	        
		 // 로그인 성공시 이동할 페이지
		 setDefaultTargetUrl("/index");
		 // 로그인 성공시 이동할 페이지로 이동
		 super.onAuthenticationSuccess(request, response, authentication);

	 }
}

SecurtiyConfig

package com.oracle.prj.auth;

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.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;

import lombok.RequiredArgsConstructor;

@Configuration
@RequiredArgsConstructor
@EnableWebSecurity
public class SecurtiyConfig {


	// 생성해둔 MemberAuthenticatorProvider를 주입받는다.
    // 해당 클래스로 memberDetailService 내부 로직을 수행하며
    // 인증 처리도 같이 진행된다
    @Autowired
    CustomAuthenticationProvider cutsomAuthenticatorProvider;

    // in memory 방식으로 인증 처리를 진행 하기 위해 기존엔 Override 하여 구현했지만
    // Spring Security 5.7.0 버전부터는 AuthenticationManagerBuilder를 직접 생성하여
    // AuthenticationManager를 생성해야 한다.
    @Autowired
    public void configure (AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(cutsomAuthenticatorProvider);
    }
    
   
    
	@Bean  //해쉬암호화 
	public BCryptPasswordEncoder passwordEncoder() {
		return new BCryptPasswordEncoder();
	}
	@Bean
	protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
		// 권한에 따라 허용하는 url 설정
		http
			.csrf().disable() //공격을 막기 위한 CSRF 토큰 검증 기능을 비활성화
			.authorizeHttpRequests() //모든 HTTP 요청에 대한 인증 및 권한 부여를 설정합니다.
			.requestMatchers("/login").permitAll()
			//.requestMatchers("/index").permitAll() //경로로 들어오는 요청은 모든 사용자에게 허용합니다
			.requestMatchers("/write").authenticated() //로그인한 사람만 보여줍니다
            .anyRequest().permitAll();//경로로 들어오는 요청은 모든 사용자에게 허용합니다
			
		//login 설정 
			http
			.formLogin() //로그인 페이지를 자동으로 생성하고, 로그인 페이지에서 제출된 인증 정보를 처리
            .loginPage("/login") // 로그인 페이지 설정
           // .loginProcessingUrl("/login") // 로그인 처리 URL 설정 POST 요청 (login 창에 입력한 데이터를 처리)
            .defaultSuccessUrl("/index") // 로그인 성공 후 이동할 페이지
            .successHandler(new MemberAuthSuccessHandler()) // 로그인 성공 후 처리할 핸들러
            .failureHandler(new MemberAuthFailureHandler());// 로그인 실패 후 처리할 핸들러
		
		
			// logout 설정
	        http
	        .logout()
	        .logoutUrl("/logout") // 로그아웃 처리 URL 설정
            .logoutSuccessUrl("/index") // 로그아웃 성공 후 이동할 페이지
            .deleteCookies("JSESSIONID"); // 로그아웃 후 쿠키
	        
		return http.build();
			
	}
	

}

userinfo.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="f" uri="http://java.sun.com/jsp/jstl/fmt"%>
<!DOCTYPE html>
<html>
<!-- Latest compiled and minified CSS -->


<head>
<meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
<title>Insert title here</title>
<style type="text/css">


.input-box{
  position:relative;
  margin:10px 0;
}

.input-box > input{
  background:transparent;
  border:none;
  border-bottom: solid 1px #ccc;
  padding:20px 0px 5px 0px;
  font-size:14pt;
  width:100%;
}

 input::placeholder{
	color:transparent;
} 

input:placeholder-shown + label{
  color:#aaa;
  font-size:14pt;
  top:15px;
}

input:focus + label, label{
  color:#8aa1a1;
  font-size:10pt;
  pointer-events: none;
  position: absolute;
  left:0px;
  top:0px;
  transition: all 0.2s ease ;
  -webkit-transition: all 0.2s ease;
  -moz-transition: all 0.2s ease;
  -o-transition: all 0.2s ease;
}

input:focus, input:not(:placeholder-shown){
  border-bottom: solid 1px #8aa1a1;
  outline:none;
}





.file-drop-area {
  position: relative;
  width: 200px;
  height: 200px;
  border: 1px dashed #ccc;
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.file-upload-button {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  cursor: pointer;
}

.file-drop-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}





.input {
	position: relative;
}

.input .eyes {
	position: absolute;
	top: 0;
	bottom: 0;
	right: 0;
	margin: auto 2px;
	height: 30px;
	font-size: 22px;
	cursor: pointer;
}

table.type09 {
	border-collapse: collapse;
	text-align: left;
	line-height: 1.5;
}

table.type09 thead th {
	padding: 10px;
	font-weight: bold;
	vertical-align: top;
	color: #369;
	border-bottom: 3px solid #036;
}

table.type09 tbody th {
	width: 150px;
	padding: 10px;
	font-weight: bold;
	vertical-align: top;
	border-bottom: 1px solid #ccc;
	background: #f3f6f7;
}

table.type09 td {
	width: 350px;
	padding: 10px;
	vertical-align: top;
	border-bottom: 1px solid #ccc;
}





</style>
	
</head>
<body>
<div id="memberjo"></div>
 <div  id="login" class="member_login" >
로그인
        <form action="/login", method="post">
			  <div class="input-box">
                <input id="username" type="text" name="username" placeholder="아이디">
                <label for="id">아이디</label>
            </div>

            <div class="input-box">
                <input id="password" type="password" name="password" placeholder="비밀번호">
                <label for="pw">비밀번호</label>
            </div>
            



            <div class="member_login_btn">
                <input type="button" class="btn btn-secondary" id="btn-login" onclick="button_login();" value="로그인">
  				<input type="button" onclick="button_join();"  class="btn btn-secondary" value="회원가입">
  				<input type="button"  id="btn_list" class="btn btn-secondary" value="처음으로">
            
            </div>
 
	



        </form>
    </div> 


</body>
<script type="text/javascript">

/* 회원가입 클릭시  */ 
function button_join() {
	$('.member_login').hide();
	$.ajax({
		type:'GET',
		url:'/memberjoin',
		success:function(data){
		
	       $('#memberjo').html(data);
	       $('#username').focus();
		}
	})
}

/* 로그인클릭시  */ 
 function button_login() {

	var username = document.getElementById("username").value;
	var password = document.getElementById("password").value;
	if ($('#username').val().trim() == '') {
		alert("아이디를 입력해주세요")
		$('#username').focus();
		return false;
	}else if ($('#password').val().trim() == '') {
		alert("비밀번호를 입력해주세요")
		$('#password').focus();
		return false;
		
	}
	$.ajax({
		type:'POST',
		url:'/login',
		data:{'username':username
			 ,'password':password
			 },
		success:function(data){
			window.location.href = '/index';
		},
		//아이디 비밀번호 에러시
		error: function () {  
		     alert('아이디 또는 비밀번호를 확인하세요');
		
		}
	
		})
	
	
	}
	
	
	


//처음으로 버튼
	$('#memberpage').on('click','#btn_list', function(){ 
	window.location.href = '/index'
	
})
</script>


</html>

🔽비밀번호 아이디 틀리면 alert창
일치시 로그인 되어짐 아이디 중복체크까지 완료

0개의 댓글