728x90
출처:
https://www.youtube.com/watch?v=VESYOJWD5d8&list=PL93mKxaRDidECgjOBjPgI3Dyo8ka6Ilqm&index=63
이번시간은 session값을 변경하려함
이건 시큐리티 때문에 좀 까다롭다.
이렇게 써주면 저 Atuthentication객체를 가져오는 것.
session에 강제 접근시도했으나 실패했음.
정상적인 흐름 그대로 실행하는 방법으로 다시 시도
(강의중 자바스크립트에서 username을 전송하는 구문이 빠져서 실행이 잘 안됐었음)
ctrl+shift+s
단축키
이거 하는 과정 줄인 단축키이다.
bean 생성
bean 등록
package com.cosblog.controller.api;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import com.cosblog.config.auth.PrincipalDetail;
import com.cosblog.dto.ResponseDto;
import com.cosblog.model.User;
import com.cosblog.service.UserService;
@RestController
public class UserApiController {
@Autowired
private UserService userService;
@Autowired
private AuthenticationManager authenticationManager;
//@Autowired //메서드 파라메터 대신 이렇게 넣어줘도 가능하다.
//private HttpSession session;
@PostMapping("/auth/joinProc")
public ResponseDto<Integer> save(@RequestBody User user) {
userService.회원가입(user);
return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);//자바오브젝트를 JSON으로 변환해서 리턴
}
@PutMapping("/user")
public ResponseDto<Integer> update(@RequestBody User user
//,@AuthenticationPrincipal PrincipalDetail principal
//,HttpSession session
) {
userService.회원수정(user);
//여기서는 트랜잭션이 종료되기 때문에 DB에 값은 변경이 됐음.
// 하지만 세션값은 변경되지 않은 상태이기 때문에 우리가 직접 세션값을 변경해줄 것임.
//세션등록
Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
SecurityContextHolder.getContext().setAuthentication(authentication);
//강제로 session에 값 저장하려 했으나 안됐음
/*
* Authentication authentication= new
* UsernamePasswordAuthenticationToken(principal,
* null,principal.getAuthorities()); SecurityContext securityContext =
* SecurityContextHolder.getContext();
* securityContext.setAuthentication(authentication);
* session.setAttribute("SPRING_SECURITY_CONTEXT", securityContext);
*/
return new ResponseDto<Integer>(HttpStatus.OK.value(), 1);//자바오브젝트를 JSON으로 변환해서 리턴
}
//전통적인 로그인 방식, 스프링 시큐리티 이용해서 로그인하면 이 방식 사용하지 않는다.
/*
* @PostMapping("/api/user/login") public ResponseDto<Integer>
* login(@RequestBody User user, HttpSession session){
* System.out.println("UserApiController:login호출됨"); User principal =
* userService.로그인(user); //접근주체
*
* if(principal != null) { session.setAttribute("principal", principal); }
*
* return new ResponseDto<Integer>(HttpStatus.OK.value(),1);
*
* }
*/
}
package com.cosblog.controller;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import com.cosblog.config.auth.PrincipalDetail;
//인증이 안된 사용자들이 출입할 수 있는 경로를 /auth만 허용할 것임
//그냥 주소가 /이면 index.jsp 허용
//static이하에 있는 /js/**, /css/**, /image/**
@Controller
public class UserController {
@GetMapping("/auth/joinForm")
public String joinForm() {
return "user/joinForm";
}
@GetMapping("/auth/loginForm")
public String loginForm() {
return "user/loginForm";
}
@GetMapping("/user/updateForm")
public String updateForm(@AuthenticationPrincipal PrincipalDetail principal) {
return "user/updateForm";
}
}
package com.cosblog.config;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.cosblog.config.auth.PrincipalDetailService;
//빈 등록 : 스프링 컨테이너에서 객체를 관리할 수 있게 하는 것
//아래 3개는 세트라고 생각해라
@Configuration //빈등록 IOC관리
@EnableWebSecurity //시큐리티 필터가 등록이 된다.
@EnableGlobalMethodSecurity(prePostEnabled = true)//특정 주소로 접근을 하면 권한 및 인증을 미리 체크하겠다는 뜻.
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private PrincipalDetailService principalDetailService;
@Bean
public AuthenticationManager authenticationManagerBean() throws Exception {
// TODO Auto-generated method stub
return super.authenticationManagerBean();
}
@Bean //IOC가 됨
public BCryptPasswordEncoder encodePWD() {
return new BCryptPasswordEncoder();
}
//시큐리티가 대신 로그인해주는데 password를 가로채기를 하는데
//해당 password가 뭘로 해쉬가 되어 회원가입이 되었는지 알아야
//같은 해쉬로 암호화해서 DB에 있는 해쉬랑 비교할 수 있음.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception{
auth.userDetailsService(principalDetailService).passwordEncoder(encodePWD());
}
@Override
protected void configure(HttpSecurity http)throws Exception{
http
.csrf().disable() //csrf 토큰 비활성화 (테스트시 걸어두는 게 좋음)
.authorizeRequests()
.antMatchers("/", "/auth/**", "/js/**", "/css/**", "/image/**","/dummy/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.formLogin()
.loginPage("/auth/loginForm")
.loginProcessingUrl("/auth/loginProc")//스프링 시큐리티가 해당 주소로 요청오는 로그인을 가로채서 대신 로그인 해준다.
.defaultSuccessUrl("/");
//.failureUrl("/fail");//실패시 보낼 Url위치 적는 방법
}
}
package com.cosblog.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.cosblog.model.RoleType;
import com.cosblog.model.User;
import com.cosblog.repository.UserRepository;
//스프링이 컴포넌트 스캔을 통해서 bean에 등록을 해줌
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private BCryptPasswordEncoder encoder;
@Transactional
public void 회원가입(User user) {
String rawPassword = user.getPassword(); //1234원문
String encPassword = encoder.encode(rawPassword); //해쉬
user.setPassword(encPassword);
user.setRole(RoleType.USER);
userRepository.save(user);
}
@Transactional
public void 회원수정(User user) {
//수정시에는 영속성 컨텍스트 User 오브젝트를 영속화시키고, 영속화된 User 오브젝트를 수정
//select를 해서 User오브젝트를 DB로부터 가져오는 이유는 영속화를 하기 위해서!
//영속화된 오브젝트를 변경하면 자동으로 DB에 update문을 날려주거든요.
User persistance = userRepository.findById(user.getId()).orElseThrow(()->{
return new IllegalArgumentException("회원 찾기 실패");
});
String rawPassword = user.getPassword();
String encPassword = encoder.encode(rawPassword);
persistance.setPassword(encPassword);
persistance.setEmail(user.getEmail());
//회원수정 함수 종료시 = 서비스 종료 = 트랜잭션 종료 = commit이 자동으로 됩니다.
//영속화된 persistance 객체의 변화가 감지되면 더티체킹이 되어 update문을 날려줌.
}
/* 이 로그인도 사용 안 할거라 삭제
* @Transactional(readOnly = true)//Select할 때 트랜잭션 시작, 서비스 종료시에 트랜잭션 종료(정합성)
* public User 로그인(User user) { return
* userRepository.findByUsernameAndPassword(user.getUsername(),
* user.getPassword()); }
*/
}
let index = {
init: function () {
$("#btn-save").on("click", () => {
//()=>{} this를 바인딩하기 위해서!
this.save();
});
$("#btn-update").on("click", () => {
//()=>{} this를 바인딩하기 위해서!
this.update();
});
// $("#btn-login").on("click", () => {
// //()=>{} this를 바인딩하기 위해서!
// this.login();
// });
},
save: function () {
//alert("user의 save함수 호출됨");
let data = {
//id값으로 찾아서 값 가져옴
username: $("#username").val(),
password: $("#password").val(),
email: $("#email").val(),
};
//console.log(data);
// ajax호출시 default가 비동기 호출
// ajax 통신을 이용해서 3개의 데이터를 json으로 변경하여 insert요청!
// ajax가 통신을 성공하고 서버가 json을 리턴해주면 자동으로 자바 오브젝트로 변환해주네요.
$.ajax({
//회원가입 수행 요청
type: "POST",
url: "/auth/joinProc",
data: JSON.stringify(data), //http body 데이터
contentType: "application/json; charset=utf-8", //body데이터가 어떤 타입인지(MIME)
dataType: "json", // 요청을 서버로 해서 응답이 왔을 때 기본적으로 모든 것이 문자열(생긴게 json이라면)=> javascript 오브젝트로 변경
})
.done(function (resp) {
alert("회원가입이 완료되었습니다.");
//console.log(resp);
location.href = "/";
})
.fail(function (error) {
alert(JSON.stringify(error));
}); //ajax 통신을 이용해서 3개의 데이터를 json으로 변경히여 insert 요청!!
},
update: function () {
let data = {
id: $("#id").val(),
username: $("#password").val(),
password: $("#password").val(),
email: $("#email").val(),
};
$.ajax({
type: "PUT",
url: "/user",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
})
.done(function (resp) {
alert("회원수정이 완료되었습니다.");
location.href = "/";
})
.fail(function (error) {
alert(JSON.stringify(error));
});
},
// login: function () {
// //alert("user의 save함수 호출됨");
// let data = {
// //id값으로 찾아서 값 가져옴
// username: $("#username").val(),
// password: $("#password").val(),
// email: $("#email").val(),
// };
// //console.log(data);
// // ajax호출시 default가 비동기 호출
// // ajax 통신을 이용해서 3개의 데이터를 json으로 변경하여 insert요청!
// // ajax가 통신을 성공하고 서버가 json을 리턴해주면 자동으로 자바 오브젝트로 변환해주네요.
// $.ajax({
// //회원가입 수행 요청
// type: "POST",
// url: "/api/user/login",
// data: JSON.stringify(data),
// contentType: "application/json; charset=utf-8", //body데이터가 어떤 타입인지(MIME)
// dataType: "json", // 요청을 서버로 해서 응답이 왔을 때 기본적으로 모든 것이 문자열(생긴게 json이라면)=> javascript 오브젝트로 변경
// })
// .done(function (resp) {
// alert("로그인이 완료되었습니다.");
// location.href = "/";
// })
// .fail(function (error) {
// alert(JSON.stringify(error));
// }); //ajax 통신을 이용해서 3개의 데이터를 json으로 변경히여 insert 요청!!
// },
};
index.init();
728x90
'Spring > Spring boot' 카테고리의 다른 글
스프링부트 강좌 63강(블로그 프로젝트) - 카카오 로그인 OAuth2.0 개념이해 (0) | 2022.01.25 |
---|---|
스프링부트 강좌 62강(블로그 프로젝트) - 카카오 로그인 환경설정 (0) | 2022.01.25 |
스프링부트 강좌 60강(블로그 프로젝트) - 회원수정 1 (0) | 2022.01.25 |
스프링부트 강좌 59강(블로그 프로젝트) - 스프링작동원리 복습 (0) | 2022.01.25 |
스프링부트 강좌 58강(블로그 프로젝트) - 글 수정하기 (0) | 2022.01.25 |
댓글