๐Ÿ“š TIL 33์ผ์ฐจ

temprmnยท2023๋…„ 7์›” 6์ผ
0
post-thumbnail

1. ๋ณธ์ธ์ด ๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ

  • ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ, ์ด๋ฉ”์ผ ์ธ์ฆ
  • ์œ ์ € ์ธ๊ฐ€ ๋ฐ ์ธ์ฆ์„ ์œ„ํ•œ ๊ธฐ๋ณธ์ ์ธ ์‹œํ๋ฆฌํ‹ฐ ํ™˜๊ฒฝ ์„ค์ •
  • ์œ„์ชฝ์— ๊ตฌํ˜„ํ•œ ๊ฒƒ๋“ค์„ ํ”„๋ก ํŠธ์™€ ์—ฐ๊ฒฐ

1-1. ๊ตฌํ˜„ ๋ฐฉ์‹ (์‚ฌ์šฉํ•œ ๊ธฐ์ˆ , ๋ณ€์ˆ˜ ํƒ€์ž… ๋“ฑ๋“ฑ ํ•˜๋‚˜๋ผ๋„ ์–ป์€ ์ )
1-2. ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ• (url ์ฃผ์†Œ, input ๊ฐ’ ์กฐ๊ฑด, output ๊ฐ’ ์กฐ๊ฑด ๋“ฑ๋“ฑ) - <ํ”„๋ก ํŠธ ๊ธฐ์ค€>
1-3. ํ•ด๋‹น ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•œ ์ด์œ ๊ฐ€ ๋ญ”์ง€ > ์–ด๋– ํ•œ ๋ชฉํ‘œ๋กœ ํ•ด๋‹น ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ฒŒ ๋๋Š”์ง€!

...๋Š” ์•„๋ž˜์— ํ•จ๊ป˜ ์ž‘์„ฑํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

0. ํ”„๋ก ํŠธ์—”๋“œ

  • ๋ฐฑ์—”๋“œ์—์„œ ์ž‘์—…ํ•œ ๊ฒฐ๊ณผ๋ฅผ ํ”„๋ก ํŠธ์—”๋“œ๋กœ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด ajax์™€ thymeleaf๋ฅผ ์‚ฌ์šฉํ–ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค๋ฉด, username์˜ ์ค‘๋ณต์„ ๊ฒ€์‚ฌํ•˜๋Š” api๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ํ˜ธ์ถœํ–ˆ๋‹ค.
// username ์ค‘๋ณต ์ฒดํฌ
@PostMapping("/signup/confirm-username/{username}")
@ResponseBody
public void checkUsername(@PathVariable("username") String username) {
    userService.checkUsername(username);
}
$.ajax({
        type: 'POST',
        url: '/api/signup/confirm-username/' + encodeURIComponent(username),
        contentType: "application/json"
    }).done(function (data, textStatus, xhr) {
        if (data !== '') {
            alert('์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์•„์ด๋”” ์ž…๋‹ˆ๋‹ค.');
            return;
        }
        alert('์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์•„์ด๋”” ์ž…๋‹ˆ๋‹ค.');
    })
        .fail(function (xhr, textStatus, errorThrown) {
            alert(errorThrown);
        });
  • ์„œ๋น„์Šค ํ•จ์ˆ˜๋“ค์€ ๋ฐฑ์—”๋“œ์—์„œ ์ฒ˜๋ฆฌํ•ด์•ผํ•œ๋‹ค๋Š” ์œ ์˜ํ•ด์„œ ์ž‘์—…ํ•˜๋ ค๊ณ  ๋…ธ๋ ฅํ–ˆ๋‹ค.

1. ํšŒ์›๊ฐ€์ž…

1-1) ํ”„๋ก ํŠธ ์ ‘๊ทผ
url -> /api/signup-page

1-2) ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ž‘์—…์„ ์ง„ํ–‰

url -> /api/signup
  • ํ”„๋ก ํŠธ๋กœ๋ถ€ํ„ฐ username(์•„์ด๋””), password(๋น„๋ฐ€๋ฒˆํ˜ธ), email(์ด๋ฉ”์ผ), nickname(๋‹‰๋„ค์ž„)์„ <form>์œผ๋กœ ๋ฐ›์•„์˜จ๋‹ค.
  • ์•„๋ž˜๋Š” SignupRequestDto ๊ตฌํ˜„๋ถ€
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class SignupRequestDto {

    @Pattern(regexp = "^(?=.*[a-z\\d]).{4,10}$", message = "์ตœ์†Œ 4์ž ์ด์ƒ, 10์ž ์ดํ•˜์ด๋ฉฐ ์•ŒํŒŒ๋ฒณ ์†Œ๋ฌธ์ž(a~z), ์ˆซ์ž(0~9) ์‚ฌ์šฉ.")
    @NotBlank
    private String username;

    @Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[!@#$%^*+=-]).{8,15}$", message = "์ตœ์†Œ 8์ž ์ด์ƒ, 15์ž ์ดํ•˜์ด๋ฉฐ ์•ŒํŒŒ๋ฒณ ๋Œ€์†Œ๋ฌธ์ž(a~z, A~Z), ์ˆซ์ž(0~9), ํŠน์ˆ˜๋ฌธ์ž(!@#$%^*+=-)๋ฅผ 1๊ฐœ ์ด์ƒ ์‚ฌ์šฉ.")
    @NotBlank
    private String password;

    @Email
    @NotBlank
    private String email;

    @NotBlank
    private String nickname;
}
  • SignupRequestDto์—๋„ @Pattern ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ์ •๊ทœํ‘œํ˜„์‹์œผ๋กœ ๊ฐ’์„ ๊ฑฐ๋ฅด๊ณ  ์žˆ์ง€๋งŒ, ํ”„๋ก ํŠธ์—์„œ๋„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋”ํ•ด์ฃผ๊ณ  ์žˆ๋‹ค. (์‹œ๊ฐ์ ์ธ ํŽธ์˜์„ฑ์„ ์œ„ํ•ด) ์•„๋ž˜๋Š” JS๋กœ ์ž‘์„ฑํ•œ check_email()์˜ ๊ตฌํ˜„๋ถ€.
function check_email() { // ์ด๋ฉ”์ผ ์ •๊ทœ์‹ ์ฒดํฌ
    var email = document.getElementById('email').value;

    // ์ด๋ฉ”์ผ ์ •๊ทœ์‹
    let regexp_email = new RegExp('^[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_.]?[0-9a-zA-Z])*.[a-zA-Z]{2,3}$')

    if (!regexp_email.test(email)) {
        document.getElementById('check_regexp_email').innerHTML = '์œ ํšจํ•˜์ง€ ์•Š์€ ์ด๋ฉ”์ผ ํ˜•์‹ ์ž…๋‹ˆ๋‹ค.';
        document.getElementById('check_regexp_email').style.color = 'red';
        return false;
    } else {
        document.getElementById('check_regexp_email').innerHTML = '์œ ํšจํ•œ ์ด๋ฉ”์ผ ํ˜•์‹ ์ž…๋‹ˆ๋‹ค.';
        document.getElementById('check_regexp_email').style.color = 'blue';
        return true;
    }
}
1-3) username ์ค‘๋ณต ํ™•์ธ
url -> /api/signup/confirm-username/{username}
  • reqeust๋กœ ๋ฐ›์„ {email} ๊ฐ’์€ @PathVariable๋กœ ๋ฐ›์•„์˜จ๋‹ค.
  • ์‹ค์ œ ํ”„๋ก ํŠธ์—์„œ๋Š” ์ด๋ฉ”์ผ ์ž…๋ ฅ์„ ๋ฐ›๋Š” <input> ์นธ์— ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.
  • ์ด๋ฉ”์ผ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋„˜์–ด์˜ค๋Š”์ง€ ํ™•์ธํ•˜๋ ค๊ณ  @PathVariable์„ ์„ ํƒํ–ˆ๋‹ค.

2. ๋กœ๊ทธ์ธ

2-1) ํ”„๋ก ํŠธ์—์„œ ์ ‘๊ทผ
url -> /api/login-page
2-2) ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์ž‘์—…์„ ์ง„ํ–‰
url -> /api/login
  • ํ”„๋ก ํŠธ๋กœ๋ถ€ํ„ฐ username(์•„์ด๋””)์™€ password(๋น„๋ฐ€๋ฒˆํ˜ธ)๋ฅผ ๋ฐ›์•„์™€ DB ๋‚ด ์œ ํšจํ•œ ๊ฐ’์ธ์ง€ ํ™•์ธํ•˜๊ณ , token์„ ์ƒ์„ฑ ํ›„ โ†’ ์ƒ์„ฑํ•œ token์„ Cookie ๊ฐ’์œผ๋กœ ์ „๋‹ฌํ•œ๋‹ค.

  • Cookie๋กœ ์ „๋‹ฌ๋œ token ๊ฐ’์€ setRequestHeader() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ Header๋กœ ์ „๋‹ฌ๋œ๋‹ค.

3. ์ด๋ฉ”์ผ ์ธ์ฆ

'์–ด๋–ป๊ฒŒ ์ธ์ฆํ•ด์•ผํ•œ๋‹ค'๋Š” ์ ˆ์ฐจ๋ฅผ ๋ช…์‹œํ•œ ๊ฒƒ์ด ์—†์–ด์„œ,

  1. ๋‚œ์ˆ˜๋ฅผ ์ƒ์„ฑํ•˜๊ณ 
  2. ๊ทธ ๋‚œ์ˆ˜๋ฅผ ๋ฉ”์ผ๋กœ ์ „์†กํ•˜๊ณ 
  3. ๋ฉ”์ผ๋กœ ์ „์†ก ๋ฐ›์€ ๋‚œ์ˆ˜์™€ ์ƒ์„ฑ๋œ ๋‚œ์ˆ˜๊ฐ€ ์ผ์น˜ํ•˜๋Š”์ง€ (๊ฐ’์„ ๋™์ผํ•˜๊ฒŒ ์ž…๋ ฅํ–ˆ๋Š”์ง€)

๋ฅผ ๊ฒ€์‚ฌํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ด๋ฉ”์ผ ์ธ์ฆ์„ ์ง„ํ–‰ํ–ˆ์Šต๋‹ˆ๋‹ค.

3-1) ์ด๋ฉ”์ผ ์ค‘๋ณต ํ™•์ธ
url -> /api/signup/confirm-email/{email}
  • reqeust๋กœ ๋ฐ›์„ {email} ๊ฐ’์€ @PathVariable๋กœ ๋ฐ›์•„์˜จ๋‹ค.
  • ์‹ค์ œ ํ”„๋ก ํŠธ์—์„œ๋Š” ์ด๋ฉ”์ผ ์ž…๋ ฅ์„ ๋ฐ›๋Š” <input> ์นธ์— ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.
  • ์ด๋ฉ”์ผ์ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋„˜์–ด์˜ค๋Š”์ง€ ํ™•์ธํ•˜๋ ค๊ณ  @PathVariable์„ ์„ ํƒํ–ˆ๋‹ค.
  • '์ค‘๋ณต ํ™•์ธ'์€ ๊ธฐ์กด์— ์กด์žฌํ•˜๋Š” user ๊ฐ’๋“ค ์‚ฌ์ด์—์„œ ์ฒดํฌํ•˜๋Š” ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•ด์„œ /api/email/~ ๋Œ€์‹  /api/signup/~ ์œผ๋กœ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ–ˆ๋‹ค.
3-2) ์ด๋ฉ”์ผ ์ „์†ก
url -> /api/email/send-email
  • request (=๋ณด๋‚ผ ์ด๋ฉ”์ผ) ๊ฐ’์€ @RequestBody๋กœ ๋ฐ›์•„์™”๋‹ค.

  • ์‹ค์ œ ํ”„๋ก ํŠธ์—์„œ๋Š” ์ด๋ฉ”์ผ ์ž…๋ ฅ์„ ๋ฐ›๋Š” <input> ์นธ์— ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

  • ์ธ์ฆ์ฝ”๋“œ ์ƒ์„ฑ์€ 6์ž๋ฆฌ์˜ ๋žœ๋คํ•œ ์ˆซ์ž์˜ ์กฐํ•ฉ์ด๋‹ค.

  • ์ธ์ฆ์ฝ”๋“œ(์ธ์ฆ๋ฒˆํ˜ธ)๋ฅผ ์ „๋‹ฌํ•  ๋•Œ๋Š” thymeleaf๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ์ „๋‹ฌํ•ด์ฃผ์—ˆ๋‹ค.

// context ์„ค์ •
private String setContext(String authcode) {
    Context context = new Context();
    context.setVariable("authcode", authcode); // ์ „๋‹ฌํ•  ๋ณ€์ˆ˜ ๋ช…์€ {authcode}
    
    return templateEngine.process("mail", context); // mail.html
}
<div style="text-align:center; border:1px solid black; font-family:verdana;">
<div style="color:blue; margin:20px 0 20px 0;"
	th:text="${authcode}"><!--์ธ์ฆ๋ฒˆํ˜ธ {authcode}๊ฐ€ ํ‘œ์‹œ๋˜๋Š” ์ž๋ฆฌ--></div>
</div>
3-3) ์ด๋ฉ”์ผ ์ธ์ฆ ์ฝ”๋“œ ํ™•์ธ
url -> api/email/confirm-authcode
  • request (=์„ค์ •๋œ ์ธ์ฆ์ฝ”๋“œ) ๊ฐ’์€ @RequestBody๋กœ ๋ฐ›์•„์™”๋‹ค.
  • ์‹ค์ œ ํ”„๋ก ํŠธ์—์„œ๋Š” ์ด๋ฉ”์ผ ์ธ์ฆ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•˜๋Š” <input> ์นธ์— ๊ฐ’์„ ๋„ฃ์œผ๋ฉด ๋œ๋‹ค.

2 ๋” ํ•˜๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ๋ชป ๊ตฌํ˜„ํ•œ ๊ธฐ๋Šฅ

  1. ๋„ค์ด๋ฒ„ API๋ฅผ ์‚ฌ์šฉํ•œ ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ํ•ด๋ณด๊ณ  ์‹ถ์—ˆ๋Š”๋ฐ ํ”„๋ก ํŠธ์— ์‹œ๊ฐ„์„ ์“ฐ๋Š๋ผ ๋ชปํ•ด๋ด์„œ ์•„์‰ฝ๋‹ค ใ… ใ… ~
    • ํ•˜์ง€๋งŒ ํ”„๋ก ํŠธ์— ์—ฐ๊ฒฐํ•ด๋ณด๋Š” ๊ฒƒ๋„... ์˜๋ฏธ๊ฐ€ ์žˆ๊ธด ํ–ˆ๋‹ค

3. ํ˜‘์—… ์‹œ ์ข‹์•˜๋˜ ์  / ์•„์‰ฌ์› ๋˜ ์  (๊นƒํ—ˆ๋ธŒ ์‚ฌ์šฉ์ด๋ผ๋˜๊ฐ€, ํŒ€ ๋‚ด์˜ ๊ทœ์น™)

์ข‹์•˜๋˜ ์ 

  1. GitHub PullRequest๋ฅผ ์ ๊ทน ํ™œ์šฉํ•œ ์ 
    • ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ ๋ธŒ๋žœ์น˜์™€ ๋ฉ”์ธ ๋ธŒ๋žœ์น˜์— ๋‚ด ์ž‘์—…์ด๋‚˜ ์‹ค์ˆ˜๊ฐ€ ์˜ํ–ฅ์ด ๊ฐ€์ง€ ์•Š์•„์„œ ์ข‹์•˜๋‹ค (ใ…Žใ…Ž)
  2. ์ปค๋ฐ‹ ๊ทœ์น™์„ ์ •ํ•˜์—ฌ์„œ ์ปค๋ฐ‹ํ•œ ์ 
    • ํŠนํžˆ ๊ฐ€๋…์„ฑ์— ์ข‹์•˜๋‹ค
  3. ๋งค์ผ ์ •ํ•ด์ง„ ์‹œ๊ฐ„์— ๊ฐ์ž ๊ทผํ™ฉ์„ ์ „ํ•˜๊ณ , ์ฝ”๋“œ๋ฆฌ๋ทฐ๋ฅผ ์ง„ํ–‰ํ•œ ์ 

์•„์‰ฌ์› ๋˜ ์ 

  1. ์ผ ๋ถ„๋ฐฐ๊ฐ€ ์–ด๋ ค์› ๋˜ ์ 
    • ์•„์ง ๋ถ€์กฑํ•˜๋‹ค๋ณด๋‹ˆ ๊ธฐ๋Šฅ์˜ ๋‚œ์ด๋„๋ฅผ ๊ฐ€๋Š ํ•˜๊ธฐ๋„ ์–ด๋ ค์›Œ์„œ ๋ถ„๋ฐฐ๊ฐ€ ์ ์ ˆํ–ˆ๋Š”์ง€ ๊ฐ€๋Š ์ด ์ž˜ ๊ฐ€์ง€ ์•Š์•˜๋‹ค
profile
`ISFJ` T 49% F 51% /

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