๐Ÿ”ฅ #16 ํšŒ์›์ •๋ณด ์ˆ˜์ • ๋ฐ Session ๋“ฑ๋ก ๋ฐฉ๋ฒ•

myeonjiยท2022๋…„ 2์›” 23์ผ
0

ํšŒ์›์ •๋ณด๋Š” ํ˜„์žฌ ๋กœ๊ทธ์ธ๋œ ์œ ์ €, ์ฆ‰ ์„ธ์…˜์—์„œ ๋“ค๊ณ ์˜ค๋ฉด ๋œ๋‹ค. ํ—ค๋”์— ์‹œํ๋ฆฌํ‹ฐ ํƒœ๊ทธ๋กœ "pricipal" ๋ณ€์ˆ˜์— ํ˜„์žฌ ์„ธ์…˜ ์ •๋ณด ๋„ฃ์–ด ๋†“์•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด ๋ณ€์ˆ˜ ์“ฐ๋ฉด ๋œ๋‹ค. (select ํ•  ํ•„์š” X)

< updateForm.jsp >

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>

<%@ include file="../layout/header.jsp"%>

<div class="container">

    <form>
        <input type="hidden" id="id" value="${principal.user.id}" />
        <div class="form-group">
            <label for="username">Username</label>
            <input type="text" value="${principal.user.username}" class="form-control" placeholder="Enter username" id="username" readonly>
        </div>

        <div class="form-group">
            <label for="password">Password</label>
            <input type="password" class="form-control" placeholder="Enter password" id="password">
        </div>

        <div class="form-group">
            <label for="email">Email</label>
            <input type="email" value="${principal.user.email}" class="form-control" placeholder="Enter email" id="email">
        </div>
    </form>
    <button id="btn-update" class="btn btn-primary">ํšŒ์›์ˆ˜์ •ํ•˜๊ธฐ</button>

</div>

<script src="/js/user.js"></script>
<%@ include file="../layout/footer.jsp"%>

์ƒ๋‹จ๋ฐ” "ํšŒ์›์ •๋ณด" ๋ฒ„ํŠผ์— /user/updateForm url์„ ๊ฑธ์–ด๋‘”๋‹ค. ์ด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹น url๋กœ ์ด๋™ํ•  ๊ฒƒ์ด๋‹ค.

id๋Š” ์ถ”ํ›„์— DB์—์„œ select ํ•˜๊ธฐ ์œ„ํ•ด hidden์œผ๋กœ ๋งŒ๋“ค์–ด์ฃผ๊ณ , Username์€ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์—†๋„๋ก input์— readonly ์†์„ฑ์„ ๋„ฃ๋Š”๋‹ค.

< UserController >

@GetMapping("/user/updateForm")
public String updateForm() {

    return "user/updateForm";
}

id="btn-update"์ธ ํšŒ์› ์ˆ˜์ • ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด user.js๊ฐ€ ์ž‘๋™ํ•œ๋‹ค.

< user.js >

.
.
.
	$("#btn-update").on("click", ()=>{ // function(){} ๋Œ€์‹  ()=>{} ๋ฅผ ์“ด ์ด์œ  : this๋ฅผ ๋ฐ”์ธ๋”ฉํ•˜๊ธฐ ์œ„ํ•ด์„œ
            this.update();
    });
.
.
.
update: function () {
        let data = {
            id: $("#id").val(),
          	username: $("#username").val(),
            password: $("#password").val(),
            email: $("#email").val()
        };

        $.ajax({
            type: "PUT",
            url: "/user",
            data: JSON.stringify(data), // http body ๋ฐ์ดํ„ฐ
            contentType: "application/json; charset=utf-8", // body ๋ฐ์ดํ„ฐ๊ฐ€ ์–ด๋–ค ํƒ€์ž…์ธ์ง€ (MIME)
            dataType: "json" // ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ํ•ด์„œ ์‘๋‹ต์ด ์™”์„ ๋•Œ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ๊ฒƒ์ด String(๋ฌธ์ž์—ด), ๋งŒ์•ฝ ์ƒ๊ธด๊ฒŒ json์ด๋ผ๋ฉด javascript ์˜ค๋ธŒ์ ํŠธ๋กœ ๋ณ€๊ฒฝ
        }).done(function (resp) {
            // ๊ฒฐ๊ณผ๊ฐ€ ์ •์ƒ์ด๋ฉด done ์‹คํ–‰
            alert("ํšŒ์›์ˆ˜์ •์ด ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
            //console.log(resp);
            location.href = "/";
        }).fail(function (error) {
            // ์‹คํŒจํ•˜๋ฉด fail ์‹คํ–‰
            alert("ํšŒ์›์ˆ˜์ •์ด ์‹คํŒจํ•˜์˜€์Šต๋‹ˆ๋‹ค.");
            alert(JSON.stringify(error));
        });
    }
.
.
.

์ˆ˜์ •์ด๊ธฐ ๋•Œ๋ฌธ์— ํƒ€์ž…์€ PUT ์œผ๋กœ ํ•˜์—ฌ /user์— ๋ฐ์ดํ„ฐ๋ฅผ ๋„˜๊ธด๋‹ค. (json ํƒ€์ž…์œผ๋กœ)

< UserApiController >

@PutMapping("/user")
public ResponseDto<Integer> update(@RequestBody User user) { // id, password, email
    userService.ํšŒ์›์ˆ˜์ •(user);
    
    return new ResponseDto<Integer>(HttpStatus.OK.value(), 1); // ํ†ต์‹  ์„ฑ๊ณต : 200, ์‹คํŒจ : 500 // ์ž๋ฐ” ์˜ค๋ธŒ์ ํŠธ๋ฅผ JSON์œผ๋กœ ๋ณ€ํ™˜ํ•ด์„œ ๋ฆฌํ„ด (Jackson)
}

< UserService >

@Transactional // ์ „์ฒด๊ฐ€ ์„ฑ๊ณตํ•ด์•ผ commit, ์‹คํŒจํ•˜๋ฉด rollback
public void ํšŒ์›์ˆ˜์ •(User user) {
    // ์ˆ˜์ •์‹œ์—๋Š” JPA ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— User ๊ฐ์ฒด๋ฅผ ์˜์†ํ™” ์‹œํ‚ค๊ณ , ์˜์†ํ™”๋œ User ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด ๋œ๋‹ค.
    // select ํ•˜์—ฌ DB์—์„œ ๊ฐ€์ ธ์™€ ์˜์†ํ™”๋ฅผ ํ•œ๋‹ค.
    // ์˜์†ํ™”๋œ ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ์ž๋™์œผ๋กœ ๋ณ€๊ฒฝ๊ฐ์ง€๋˜์–ด (๋”ํ‹ฐ์ฒดํ‚น) DB์— update ๋œ๋‹ค. (flush)
    User persistance = userRepository.findById(user.getId()) // select ํ•˜์—ฌ ์˜์†ํ™”
            .orElseThrow(()->{
                return new IllegalArgumentException("ํšŒ์›์ด ์กด์žฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. id : "+user.getId());
            });

    String rawPassword = user.getPassword();
    String encPassword = encoder.encode(rawPassword);

    persistance.setPassword(encPassword); // ์˜์†ํ™” ๋˜์–ด ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝ
    persistance.setEmail(user.getEmail());

    // ํšŒ์› ์ˆ˜์ • ํ•จ์ˆ˜ ์ข…๋ฃŒ ์‹œ(Service ์ข…๋ฃŒ ์‹œ) -> ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ -> commit(์˜๊ตฌ์ )์ด ์ž๋™์œผ๋กœ ๋œ๋‹ค.
    // ์˜์†ํ™”๋œ persistance ๊ฐ์ฒด์˜ ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€๋˜๋ฉด ๋”ํ‹ฐ์ฒดํ‚น ๋˜์–ด ์ž๋™์œผ๋กœ DB์— update๋ฌธ์„ ๋‚ ๋ ค์ค€๋‹ค.
}

์„œ๋น„์Šค์—๋Š” ํŠธ๋žœ์žญ์…˜์„ ๊ฑด๋‹ค.
๊ทธ๋Ÿฌ๋ฉด DB์—์„œ selectํ•œ ๊ฐ์ฒด๋ฅผ ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ์— ์˜์†ํ™” ์‹œํ‚ค๊ณ , ์˜์†ํ™” ๋˜์–ด ์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.
๊ทธ๋Ÿฌ๋ฉด ํŠธ๋žœ์žญ์…˜์ด ๋๋‚œ ํ›„ ๋‹ค์‹œ ๋งํ•ด์„œ Service๊ฐ€ ๋๋‚œ ํ›„์— ๋”ํ‹ฐ์ฒดํ‚น์„ ํ•˜์—ฌ DB์— ๋ณ€๊ฒฝ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ flush ๋  ๊ฒƒ์ด๋‹ค.


ํ˜„์žฌ ์ƒํƒœ๋Š” ํšŒ์›์ˆ˜์ •์„ ํ•˜๋ฉด DB ๋ฐ์ดํ„ฐ๋Š” ๋ฐ”๋€Œ์ง€๋งŒ, ์„ธ์…˜์€ ๋ฐ”๋€Œ์ง€ ์•Š์•˜๋‹ค.
๋‹ค์‹œ ํšŒ์›์ˆ˜์ •์„ ๋“ค์–ด๊ฐ€๋ฉด ๋ฐ”๊พธ๊ธฐ ์ „ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚˜ํƒ€๋‚  ๊ฒƒ์ด๋‹ค.
(๋ฌผ๋ก  ๋ฐ์ดํ„ฐ๋Š” DB์— ๋ฐ”๋€Œ์–ด ์žˆ์ง€๋งŒ!!)

๋”ฐ๋ผ์„œ ํšŒ์›์ˆ˜์ •์„ ํ•˜๋ฉด ์„ธ์…˜ ๊ฐ’(ํ˜„์žฌ ๋กœ๊ทธ์ธ ๋˜์–ด ์žˆ๋Š”)๋„ ๋™์‹œ์—, ์ฆ‰์‹œ(?) ๋ฐ”๋€Œ์–ด์•ผ ํ•œ๋‹ค.
์„ธ์…˜ ์•ˆ์˜ ์‹œํ๋ฆฌํ‹ฐ ์ปจํ…์ŠคํŠธ์— Authentication ๊ฐ์ฒด๋ฅผ ๊ฐ•์ œ๋กœ ๋„ฃ์–ด์ฃผ๋Š” ๊ฒƒ์ด๋‹ค. (์‹œํ๋ฆฌํ‹ฐ ์ปจํ…์Šค๋Š” Authentication๋งŒ ๊ฐ€๋Šฅ)

์„ธ์…˜ ๋“ฑ๋ก

< SecurityConfig >

@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
    return super.authenticationManagerBean();
}

AuthenticationManager ๊ฐ€ Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด Manager๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.

< UserApiController >

.
.
.

	// ์„ธ์…˜ ๋“ฑ๋ก (DB๊ฐ€ ๋ณ€๊ฒฝ๋œ ํ›„์˜ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์™€์•ผ ํ•˜๋ฏ€๋กœ Service๊ฐ€ ๋๋‚œ ํ›„(=ํŠธ๋žœ์žญ์…˜ ๋๋‚œ ํ›„)์— ์ด๋ฃจ์–ด์ ธ์•ผ ํ•œ๋‹ค. ๋”ฐ๋ผ์„œ Controller์—์„œ ์ง„ํ–‰
    Authentication authentication = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(), user.getPassword()));
    SecurityContextHolder.getContext().setAuthentication(authentication);
.
.
.

Authentication ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด์„œ session์— ์ €์žฅํ•ด์•ผ ํ•œ๋‹ค!!

Service๊ฐ€ ๋๋‚˜๊ณ  ํŠธ๋žœ์žญ์…˜์ด ๋๋‚˜๊ณ  DB์— ๋ณ€๊ฒฝ์ด ๋ฐ˜์˜๋œ ํ›„์— ์ด๋ฃจ์–ด์ ธ์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— UserApiController์—์„œ ์ง„ํ–‰ํ•œ๋‹ค.

ํ๋ฆ„์€ ์œ„์ฒ˜๋Ÿผ ๋œ๋‹ค.

๐ŸŽˆ Session ๋“ฑ๋ก ์ •๋ฆฌ

  1. ์„ธ์…˜์„ ๋“ฑ๋กํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” HttpSession์˜ SecurityContextHolder - SecurityContext ์•ˆ์— Authentication ๊ฐ์ฒด๋ฅผ ๋“ฑ๋กํ•ด์•ผ ํ•œ๋‹ค.

  2. ๋‚ด๊ฐ€ ๊ฐ•์ œ๋กœ Authentication ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์—†์œผ๋ฏ€๋กœ AuthenticationManager ๋ฅผ ํ†ตํ•ด Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

  3. AuthenticationManager ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด SecurityConfig์— ์ƒ์„ฑ ํ›„ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•˜์—ฌ, ์Šคํ”„๋ง์ด IoC๋กœ ๊ด€๋ฆฌํ•˜๊ฒŒ ํ•œ๋‹ค.

  4. AuthenticationManager ๋ฅผ ํ™œ์šฉํ•˜์—ฌ, ์ˆ˜์ •๋œ(Service์—์„œ ์ˆ˜์ •๋˜๊ณ  DB ๋ณ€๊ฒฝ๊นŒ์ง€ ์™„๋ฃŒ๋œ) User ๊ฐ์ฒด์˜ username ๊ณผ password๋กœ ์ƒˆ๋กœ์šด ํ† ํฐ์„ ๋งŒ๋“ค์–ด์„œ Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

  5. Authentication ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค ๋•Œ ํ•„์š”ํ•œ ์กฐ๊ฑด์€ DB์— ํ•ด๋‹น ์œ ์ €๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

  6. ๋”ฐ๋ผ์„œ username์„ UserDetailService์— ๋˜์ง€๊ณ , UserDetailService๊ฐ€ DB์— ์ ‘๊ทผํ•˜์—ฌ ํ™•์ธํ•œ๋‹ค. ์ด๊ฑธ ํ† ๋Œ€๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ๋„ ํ™•์ธํ•ด์•ผ ํ•œ๋‹ค.

  7. AuthenticationManager ๊ฐ€ ์ด์ œ password๋ฅผ BCrypt๋กœ ์ธ์ฝ”๋”ฉํ•˜์—ฌ DB์— ๋‹ค์‹œ ํ™•์ธํ•œ ํ›„, ๋งž์œผ๋ฉด Authentication ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

  8. HttpSession์˜ SecurityContextHolder ์•ˆ์— SecurityContext ์•ˆ์— ์žˆ๋Š” Authentication ๊ฐ์ฒด๋ฅผ ์šฐ๋ฆฌ๊ฐ€ ๋งŒ๋“  ์ƒˆ๋กœ์šด Authentication์œผ๋กœ ๋ฎ๋Š”๋‹ค. ์ฆ‰, ๊ธฐ์กด์˜ ์„ธ์…˜ ๊ฐ’์„ ์ƒˆ๋กœ ๋งŒ๋“  ๊ฐ’(์ƒˆ๋กœ ๋งŒ๋“ค์–ด์ง„ Authentication ๊ฐ์ฒด)์œผ๋กœ ๋ณ€๊ฒฝํ•œ๋‹ค.

  9. ์ตœ์ข…์ ์œผ๋กœ ์‹œํ๋ฆฌํ‹ฐ ์ปจํ…์ŠคํŠธ์— ๋„ฃ์–ด์ง„ ๊ฒƒ์ด๋‹ค.

์ฐธ๊ณ 

profile
๐Ÿ“š

0๊ฐœ์˜ ๋Œ“๊ธ€