관리 메뉴

DeseoDeSeo

[Spring] mvc06, Security 로그아웃, 회원정보수정, 프로필 사진 변경 본문

spring

[Spring] mvc06, Security 로그아웃, 회원정보수정, 프로필 사진 변경

deseodeseo 2023. 10. 16. 17:58
main.jsp
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
	<!-- Spring Security에서 제공하는 계정정보(SecurityContext안에 계정 정보 가져오기 -->
	<!-- 로그인 한 계정정보 memberuserdetail~에서 memberuser를 가져와서 mvo에 저장함. -->
	<!-- 09/27수. memberuser를 의미하는 거임. 아래 내용이.  -->
<c:set var="mvo" value="${SPRING_SECURITY_CONTEXT.authentication.principal}" />
	<!-- 권한 정보도 가져옴. -->
<c:set var="auth" value="${SPRING_SECURITY_CONTEXT.authentication.authorities}" />

○ 상단에 추가

 

○ 정보 가져오는 곳에 .member추가 

<input type="hidden" name="memID" value="${mvo.member.memID}">
<td><input readonly="readonly" value="${mvo.member.memName}" type="text"  name ="writer" class ="form-control"></td>

 

⛧ 로그아웃

 

header.jsp

로그아웃 버튼을 눌러서 이동하는 곳 ! 

로그아웃은 get방식이 아니라 post방식으로 요청해야한다.

<li><a href="javascript:logout()"> <span class="glyphicon glyphicon-log-out">로그아웃</span> </a></li>

nav태그 이후에

비동기방식: 코드가 순차적으로 실행되지 않음. 응답 기다리지 않고 바로 다음 작업을 수행한다.
AJAX: 웹 애플리케이션에서 비동기적으로 데이터를 요청하고 응답을 처리할 수 있도록 해주는 기술
          - 웹 페이지를 새로고침하지 않고 웹페이지 업데이트 가능.
<script type="text/javascript">
	//CSRF 토큰 값 가져오기
	var csrfHeaderName= "${_csrf.headerName}";
	var csrfTokenName= "${_csrf.token}";
	//비동기방식임.
	function logout(){
		$.ajax({
			url:"${contextPath}/logout",
			type: "post",
			beforeSend : function(xhr){
				xhr.setRequestHeader(csrfHeaderName, csrfTokenName);
			},
			success: function(){
				//비동기방식임.
				location.href="${contextPath}/";
			},
			error: function(){
				alert("error");
			}
		});
	}
 
 </script>

 

회원 정보 수정

여기로 이동

 @RequestMapping("/updateForm.do") 
	 public String updateForm() { 
		 return "member/updateForm"; 
		 }

 

updateForm.jsp
<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
	<!-- Spring Security에서 제공하는 계정정보(SecurityContext안에 계정 정보 가져오기 -->
	<!-- 로그인 한 계정정보 memberuserdetail~에서 memberuser를 가져와서 mvo에 저장함. -->
	<!-- 09/27수. memberuser를 의미하는 거임. 아래 내용이.  -->
<c:set var="mvo" value="${SPRING_SECURITY_CONTEXT.authentication.principal}" />
	<!-- 권한 정보도 가져옴. -->
<c:set var="auth" value="${SPRING_SECURITY_CONTEXT.authentication.authorities}" />

.

데이터 가져오는 곳에 .member 추가

<input type="hidden" name="memID" id="memID" value="${mvo.member.memID}">
main.jsp > function makeview( )
:
mvo안에 member가져와서 거기서 ID를 비교하게 함.
if("${mvo.member.memID}" == obj.memID){

로그인 해야 글쓰기 버튼이 보이도록

if(${not empty mvo.member}) {
    listHtml +="<tr>";
    listHtml +="<td colspan ='5'>";
    listHtml +="<button class 'btn btn-primary btn-sm' onclick='goForm()'>글쓰기 </button>";
    listHtml +="</td>";
    listHtml +="</tr>";
 }
 listHtml += '</table>';

 main의 글쓰기 부분에서 데이터 가져오는 부분을 value="${mvo.member.memID}"로 바꿔줌

login.do > if(cnt==1) > 
return "redirect:/loginForm.do";
main.jsp
$(document).ready(function(){
			//html이 다 로딩되고나서 아래의 코드를 실행함.
			if(${param.error!= null}) {
            $("#messageType").attr("class","modal-content panel-warning");
            $(".modal-body").text("아이디와 비밀번호를 확인해주세요");
            $(".modal-title").text("실패메세지");
            $("#myMessage").modal("show");
            
            if(${not empty msgType}){
            	if(${msgType eq "성공메세지"}){
                  $("#messageType").attr("class", "modal-content panel-success");
                  }
                  $("#myMessage").mmodal("show");
                  }
			
		});
header.jsp
: 회원정보 수정하기 위한 security데이터를 가져옴.
	<!-- context-path값(=controller)을 내장객체 변수로 저장 -->
	<c:set var="contextPath" value="${pageContext.request.contextPath }" />
	<%@ taglib prefix="security" uri="http://www.springframework.org/security/tags" %>
	<!-- Spring Security에서 제공하는 계정정보(SecurityContext안에 계정 정보 가져오기 -->
	<!-- 로그인 한 계정정보 memberuserdetail~에서 memberuser를 가져와서 mvo에 저장함. -->
	<!- memberuser를 의미하는 거임. 아래 내용이.  -->
	<c:set var="mvo" value="${SPRING_SECURITY_CONTEXT.authentication.principal}" />
	<!-- 권한 정보도 가져옴. -->
	<c:set var="auth" value="${SPRING_SECURITY_CONTEXT.authentication.authorities}" />
MemberController.java
@Autowired
private MemberUserDetailsService MemberUserDetailsService;
//회원정보 수정 후 Spring Security Context에 접근하기 위한 객체
Authentication  
 :  내가 만든 MemberUserDetailsService를 통해 DB안에 값을 넣는 일도 하지만 Contextholder에 속한 Context에 있는 회원의 값을 가져올 수 있다. ( 로그인 정보는 Contextholder에 저장함.)

1. 기존의 memberUser(회원정보)를 가져옴.
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();

                    기존 Context 회원정보 가져오기
MemberUser userAccount = (MemberUser)authentication.getPrincipal();
                                                                          authentication.getPrincipal() : 
user타입으로 반환됨.
                     authentication: 기존 권한 정보, 회원 아이디를 매개변수로
Authentication newAuthentication = createNewAuthentication(authentication, userAccount.getMember().getMemID());
 2. 
새로운 newAuthentication를 authentication에 넣음. ( 기존권한과 아이디 )
    - Security Context안에 새로운(다시 가져온) 회원정보 넣기
SecurityContextHolder.getContext().setAuthentication(newAuthentication);
private Authentication createNewAuthentication(Authentication currentAuth, String username) {
    UserDetails newPrincipal = MemberUserDetailsService.loadUserByUsername(username);
    UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(newPrincipal, currentAuth.getCredentials(), newPrincipal.getAuthorities());
		newAuth.setDetails(currentAuth.getDetails());
		return newAuth; //4. 새로운 auth를 반환. 권한
	}
○ createNewAuthentication 클래스는 리턴값이 Authentication.
○ 여기에서 새롭게 db의 회원정보를 가져옴  (로그인)
3. 위에서 받아온걸로 로그인함. UserDetails newPrincipal = MemberUserDetailsService.loadUserByUsername(username);
     비밀번호 관련 보안작업 해야함.   getCredentials() :
UsernamePasswordAuthenticationToken    newAuth 
       = new      UsernamePasswordAuthenticationToken  (   newPrincipal, currentAuth.getCredentials(  ),                newPrincipal.getAuthorities(  ) );

4. 새로운 auth를 반환. 권한
    return newAuth;

다시 update.do로 돌아감.

5. 새로운 권한(newAuthentication)을 다시 넣어줌.
SecurityContextHolder.getContext(  ). setAuthentication  ( newAuthentication ) ;
return " redirect:/ " ;
MemberController.java
> update.do

< 주석 처리 >

else {
					//09/27화요일. session이 없으니까 
			//		Member mvo = (Member)session.getAttribute("mvo");
			//		m.setMemProfile(mvo.getMemProfile());
if(cnt ==1) {

	rttr.addFlashAttribute("msgType", "성공메세지");
	rttr.addFlashAttribute("msg", "회원 정보 수정에 성공했습니다.");
	Member info = mapper.getMember(m.getMemID());

	//session.setAttribute("mvo", info);
    Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
	MemberUser userAccount = (MemberUser)authentication.getPrincipal(); //authentication.getPrincipal() : user타입으로 반환됨.
    SecurityContextHolder.getContext().setAuthentication(newAuthentication);
    	return "redirect:/";
				
}else {
		rttr.addFlashAttribute("msgType", "실패메세지");
		rttr.addFlashAttribute("msg", "회원 정보 수정에 실패했습니다.");
		return "redirect:/updateForm.do";
		}
			}			
		}

세션 부분 주석 처리

○  회원정보 수정 성공 시, Spring Security Context에 회원정보를 다시 넣음.

  실제 Spring Security기능을 실행하는 Authentication 객체 가져오기

MemberuserDetailsService.java 
> loadUserByUsername

세션에 저장하면 보안에 취약 ➜ 서버자체의 보안 장소인 Spring context holder에 저장함.

if(mvo != null) {
			// 해당 사용자가 有
			return new MemberUser(mvo);
			//Spring Security Context안에 회원의 정보를 저장.
		}else {
			//해당 사용자가 無
			throw new UsernameNotFoundException("user with username" + username + "does not exist.");
		}

 

프로필 사진 변경

여기로 이동

membercontroller.java
@RequestMapping("/imageform.do")
	public String imageForm() {
		
		return"member/imageForm";
	}
imageForm.jsp
	<!-- 09/27수. memberuser를 의미하는 거임. 아래 내용이.  -->
<c:set var="mvo" value="${SPRING_SECURITY_CONTEXT.authentication.principal}" />
	<!-- 권한 정보도 가져옴. -->
<c:set var="auth" value="${SPRING_SECURITY_CONTEXT.authentication.authorities}" />
<c:set var="contextPath" value="${pageContext.request.contextPath}" />

추가

<td>${mvo.member.memID}</td>

member. 추가

 

membercontroller.java
package kr.spring.controller;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.oreilly.servlet.MultipartRequest;
import com.oreilly.servlet.multipart.DefaultFileRenamePolicy;

import kr.spring.entity.Auth;
import kr.spring.entity.Member;
import kr.spring.entity.MemberUser;
import kr.spring.mapper.MemberMapper;
import kr.spring.security.MemberUserDetailsService;

@Controller

public class MemberController {
//	mapper만드는 법 기억해야됨.
	@Autowired
	private MemberMapper mapper;
	@Autowired // 내가 만들어 놓은 비밀번호 암호화 객체를 주입받아 사용하겠다. !!!!!!!!!!!!!! 이게 securityConfig.java에서 옴.
	private PasswordEncoder pwEncoder;
	//09/27
	@Autowired
	private MemberUserDetailsService MemberUserDetailsService;
	//회원정보 수정 후 Spring Security Context에 접근하기 위한 객체
	
	@GetMapping("/access-denied")    //로그인을 안 하고 특정 페이지를 요청했을 때 요청되는 url.
	public String showAccessDenied() {
		return "access-denied";
	}
	

	@RequestMapping("/joinForm.do")
	public String joinForm() {
		return "member/joinForm";
	}
	@RequestMapping("/registerCheck.do")
	public @ResponseBody int registerCheck(@RequestParam("memID") String memID) {
		//registercheck로 memid넘어옴.
		Member m = mapper.registerCheck(memID);
		// 여기서 membermapper.java로 이동함.
		// m == null -> 아이디 중복 사용 가능함.
		// m != null -> 아이디 사용 불가능
		if(m != null || memID.equals("")) {
			return 0;
		}else {
			return 1;
		}
	}
	@RequestMapping("/join.do")
	public String join(Member m, RedirectAttributes rttr, HttpSession session) {
		System.out.println("회원가입 기능요청");
		
		//유효성 검사
		if(m.getMemID() ==null || m.getMemID().equals("")|| m.getMemPassword()==null || m.getMemPassword().equals("")||
				m.getMemName()==null || m.getMemName().equals("")|| m.getMemAge() ==0 || m.getMemEmail() == null ||
				m.getMemEmail().equals("")||m.getAuthList().size()==0) {
			//회원 가입을 할 수 없다 하나라도 누락되어 있기 때문에
			
			//실패시 joinForm.do로 msgType과 msg내용을 보내야함.
			rttr.addFlashAttribute("msgType", "실패메세지");
			rttr.addFlashAttribute("msg", "모든 내용을 입력하세요.");
			return "redirect:/joinForm.do";
			//redirect방식에서는 model에 데이터 저장 불가.
			//forward방식에서만 model에 데이터저장 가능.
			//RedirectAttributes - 리다이렉트 방식으로 이동할 때 보낼 데이터를 저장하는 객체 
		}else {
			//회원 가입 가능

			//null값 대신 넣으려구.
			m.setMemProfile("");
			//비밀번호 암호화 !!!!!!!!!!!!!!요기서 
			String encyPw = pwEncoder.encode(m.getMemPassword());
			m.setMemPassword(encyPw);

			
			int cnt = mapper.join(m);
			//회원가입 후 index.jsp로 이동시키시오.
			// 추가 : 권한 테이블에 회원의 권한을 저장하기 (09/25 월)
			//m은 회원가입할 때 정보들임. 
			List<Auth> list = m.getAuthList();
			//권한을 여러개 선택할 수 있으니가 list로 받아옴. ?!
			for(Auth auth : list) {
				//Auth형태로 받아올거임.
				if(auth.getAuth() != null) {
					//가져온 권한 값이 있을 때만 권한테이블에 값 넣기
					Auth saveVO = new Auth();
					saveVO.setMemID(m.getMemID()); // 회원 아이디 넣기
					saveVO.setAuth(auth.getAuth()); //권한 넣기
					//권한 저장
					mapper.authInsert(saveVO);
					
				}
			}
			

			
			if(cnt==1) {
				System.out.println("회원가입 성공");
				rttr.addFlashAttribute("msgType", "성공메세지");
				rttr.addFlashAttribute("msg", "회원가입에 성공했습니다.");
				//회원가입 성공 시 로그인 처리까지 시키기
				
				//09/25 회원가입 성공 시 회원정보 + 권한정보까지 가져오기
			//	Member mvo = mapper.getMember(m.getMemID());				
			//  session.setAttribute("mvo", mvo);
				//mvo라는 이름으로 m을 넣겠다.
				//성공시 main으로 이동함,
				return "redirect:/loginForm.do";
			}else {
				System.out.println("회원가입 실패.");
				rttr.addFlashAttribute("msgType", "실패메세지");
				rttr.addFlashAttribute("msg", "회원가입에 실패했습니다.");
				return "redirect:/joinForm.do" ;
			}
			
		}
			
		}
//	@RequestMapping("/logout.do") 
//	public String logout(HttpSession session) {
//		//session을 사용하고 싶으면 매개변수에 적으면 된다.
//		session.invalidate();
//		//로그아웃 기능
//		System.out.println("로그아웃 실행");
//		// 스프링 보안에서는 개인당 세션으로 구분함. 
//		return "redirect:/";
//	}
	
	@RequestMapping("/loginForm.do")
	public String loginForm() {
		
		return "member/loginForm";
	}
	
	
	
	/*
	 * @RequestMapping("/Login.do") public String login(RedirectAttributes rttr,
	 * Member m, HttpSession session) { //문제 // mapper에 login이라는 메소드 이름으로 로그인 기능을
	 * 수행하시오. // 로그인 성공 시 -> index.jsp 이동 후, 로그인에 성공했습니다 modal창 띄우기 // 로그인 실패 시 ->
	 * login.jsp 이동 후, 로그인에 실패했습니다 modal 창 띄우기 Member mvo =mapper.login(m); //mvo는
	 * 실패하면 null이 들어감. //mvo가 실패하지 않는다면 // 추가 비밀번호 일치여부 체크 if(mvo != null &&
	 * pwEncoder.matches(m.getMemPassword(), mvo.getMemPassword()) ) {
	 * 
	 * //답을 가져와서 matches가 일치한지 알려줌. true, false로 알려줌.
	 * rttr.addFlashAttribute("msgType", "성공메세지"); rttr.addFlashAttribute("msg",
	 * "로그인에 성공했습니다."); session.setAttribute("mvo", mvo); return "redirect:/";
	 * 
	 * }else { rttr.addFlashAttribute("msgType", "실패메세지");
	 * rttr.addFlashAttribute("msg", "로그인에 실패했습니다."); return
	 * "redirect:/loginForm.do"; }
	 * } 
	 */
	
	 @RequestMapping("/updateForm.do") 
	 public String updateForm() { 
		 return "member/updateForm"; 
		 }

	
	@RequestMapping("/update.do")
	public String update(Member m, RedirectAttributes rttr, HttpSession session) {
		
		//문제
		//mapper의 update메서드를 통해 해당 회원의 정보를 수정하시오.
		// 조건1 : 하나라도 입력안한 데이터가 있으면 updateForm.jsp로 다시 돌려보내면서 
		//        updateForm.jsp에서는 "모든 내용을 입력하세요"라는 모달창을 띄우세요.
		// 조건 2: 회원 수정에 실패 했을 때는 joinForm.jsp로 다시 돌려보내면서
		//       joinForm.jsp에서는 "회원 수정이 실패했습니다."라는 모달창을 띄우세요.
		// 조건 3 : 회원수정에 성공했을 떄는 index.jsp로 다시 돌려보내면서
		//         index.jsp에서는 "회원 정보 수정에 성공했습니다."라는 모달창을 띄우세요.
	
		if(m.getMemID() ==null || m.getMemID().equals("")|| m.getMemPassword()==null || m.getMemPassword().equals("")||
				m.getMemName()==null || m.getMemName().equals("")|| m.getMemAge() ==0 || m.getMemEmail() == null ||
				m.getMemEmail().equals("") || m.getAuthList().size()==0) {
			rttr.addFlashAttribute("msgType", "실패메세지");
			rttr.addFlashAttribute("msg", "모든 내용을 입력하세요.");
			return "redirect:/updateForm.do";
		}else {
					//09/27화요일. session이 없으니까 
			//		Member mvo = (Member)session.getAttribute("mvo");
			//		m.setMemProfile(mvo.getMemProfile());
					
					//비밀번호 암호화
					String encyPw = pwEncoder.encode(m.getMemPassword());
					m.setMemPassword(encyPw);
					
					//권한 삭제
					mapper.authDelete(m.getMemID());
					//권한 입력
					List<Auth> list = m.getAuthList();
					//권한을 여러개 선택할 수 있으니가 list로 받아옴. ?!
					for(Auth auth : list) {
						//Auth형태로 받아올거임.
						if(auth.getAuth() != null) {
							//가져온 권한 값이 있을 때만 권한테이블에 값 넣기
							Auth saveVO = new Auth();
							saveVO.setMemID(m.getMemID()); // 회원 아이디 넣기
							saveVO.setAuth(auth.getAuth()); //권한 넣기
							//권한 저장
							mapper.authInsert(saveVO);
						}
					}
					
				int cnt =mapper.update(m);
				
				if(cnt ==1) {

					rttr.addFlashAttribute("msgType", "성공메세지");
					rttr.addFlashAttribute("msg", "회원 정보 수정에 성공했습니다.");
					Member info = mapper.getMember(m.getMemID());
				//09월 26일! m에는 부족한 정보가 있어서 info로 새롭게 객체 생성
				//session.setAttribute("mvo", info);
				
				// 09/27일 회원 정보 수정 성공 시 Spring Security context에 회원정보 다시 넣기
				// 실제 Spring Security기능을 실행하는 Authentication 객체 가져오기
				// Authentication 객체는 내가 만든 MemberUserDetailsService를 통해 Db안에 값을 넣는 일도 하지만
				// Contextholder 속한 Context에 있는 회원의 값을 가져올 수 있다.
				//1. 기존의 memberUser(회원정보)를 가져옴.
					Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
				//기존 Context 회원정보 가져오기
					MemberUser userAccount = (MemberUser)authentication.getPrincipal(); //authentication.getPrincipal() : user타입으로 반환됨.
				//createNewAuthentication()를 통해서 수정된(새로운) 회원정보 다시 가져오기
				// authentication: 기존 권한 정보, 회원 아이디를 매개변수로
					Authentication newAuthentication = createNewAuthentication(authentication, userAccount.getMember().getMemID());
				// 2. 새로운 newAuthentication를 authentication에 넣음. ( 기존권한과 아이디)
				//Security Context안에 새로운(다시 가져온) 회원정보 넣기
				//5. 새로운 권한(newAuthentication)을 다시 넣어줌.
					SecurityContextHolder.getContext().setAuthentication(newAuthentication);
					return "redirect:/";
				
			}else {

				rttr.addFlashAttribute("msgType", "실패메세지");
				rttr.addFlashAttribute("msg", "회원 정보 수정에 실패했습니다.");
				return "redirect:/updateForm.do";
			}
			}
			
			
		}

	
	//09/27 수요일
	private Authentication createNewAuthentication(Authentication currentAuth, String username) {
		//여기에서 새롭게 db의 회원정보를 가져올 것 이다.(로그인)
		//3. 위에서 받아온걸로 로그인함.
		UserDetails newPrincipal = MemberUserDetailsService.loadUserByUsername(username);
		// 비밀번호 관련 보안작업 해야함.   getCredentials() :
		UsernamePasswordAuthenticationToken newAuth = new UsernamePasswordAuthenticationToken(newPrincipal, currentAuth.getCredentials(), newPrincipal.getAuthorities());
		
		newAuth.setDetails(currentAuth.getDetails());
		
		return newAuth; //4. 새로운 auth를 반환. 권한
	}


	@RequestMapping("/imageform.do")
	public String immeageForm() {
		
		return"member/imageForm";
	}
	@RequestMapping("/imageUpdate.do")
	public String imageUpdate(HttpServletRequest request, HttpSession session, RedirectAttributes rttr) {
		
		//파일 업로드를 할 수 있게 도와주는 객체 필요.(cos.jar안에 있음)
		//파일 업로드를 할 수 있게 도와주는 MultipartRequest 객체를 생성하기 위해서는 
		// 5개의 정보가 필요하다.
		// 요청 데이터, 저장경로, 최대 크기, 인코딩, 파일명 중복제거 
		MultipartRequest multi = null;
		//저장경로
		String savePath = request.getRealPath("resources/upload");
		
		//이미지 최대크기
		int fileMaxSize = 10*1024*1024;
		//1.기본 해당 프로필 이미지 삭제
		// - 내가 현재 로그인 한 사람의 프로필 값을 가져와야함.
		//String memID = ((Member)session.getAttribute("mvo")).getMemID();
		
		
		//객체 생성
		try {
			multi =new MultipartRequest(request,savePath, fileMaxSize, "UTF-8", new DefaultFileRenamePolicy() );
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		String memID = multi.getParameter("memID");
				//getMember메서드는 memID와 일치하는 회원의 정보(Member)를가져온다.
		String oldImg =mapper.getMember(memID).getMemProfile();
				
		//기존의 프로필 사진 삭제
		//해당 경로안에 파일을 가져오겠다.
		File oldFile = new File(savePath+"/"+oldImg);
		if(oldFile.exists()) {
			oldFile.delete();
				}
		
		//내가 업로드한 파일 가져오기
		File file = multi.getFile("memProfile");
		//멤버 프로파일로 보냄. 객체 생성 후
		if(file != null) {
			//업로드가 된 상태
			//System.out.println(file.getName());
			String ext = file.getName().substring(file.getName().lastIndexOf(".")+1);
			ext=ext.toUpperCase();
			
			if(!(ext.equals("PNG") ||ext.equals("GIF")||ext.equals("JPG"))) {
				if(file.exists()) {
					file.delete();
					rttr.addFlashAttribute("msgType", "실패메세지");
					rttr.addFlashAttribute("msg", "이미지 파일만 가능합니다.");
					return "redirect:/imageForm.do";
				}
			}
			
			
		}
		
	
		// 업로드한 파일의 이름을 가져오는 코드
		String newProfile = multi.getFilesystemName("memProfile");
		
		Member mvo= new Member();
		mvo.setMemID(memID);
		mvo.setMemProfile(newProfile);
		
		int cnt = mapper.profileUpdate(mvo);
		
		//사진 업데이트 후 수정된 회원정보를 다시 가져와서 세션에 담기
		// Member m  =mapper.getMember(memID);
		// session.setAttribute("mvo", m);
		Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
		//기존 Context 회원정보 가져오기
			MemberUser userAccount = (MemberUser)authentication.getPrincipal(); //authentication.getPrincipal() : user타입으로 반환됨.
		//createNewAuthentication()를 통해서 수정된(새로운) 회원정보 다시 가져오기
		// authentication: 기존 권한 정보, 회원 아이디를 매개변수로
			Authentication newAuthentication = createNewAuthentication(authentication, userAccount.getMember().getMemID());
		// 2. 새로운 newAuthentication를 authentication에 넣음. ( 기존권한과 아이디)
		//Security Context안에 새로운(다시 가져온) 회원정보 넣기
		//5. 새로운 권한(newAuthentication)을 다시 넣어줌.
			SecurityContextHolder.getContext().setAuthentication(newAuthentication);
		
		rttr.addFlashAttribute("msgType", "성공메세지");
		rttr.addFlashAttribute("msg", "이미지 변경이 성공했습니다.");
		return "redirect:/";
	}
		
}