- ๋ณธ์ธ์ธ์ฆ ํ ์ฌ์ฉ์๊ฐ ์ ํํ ์ฝ๊ด๋์, ์ด๋ฆ, ์๋ ์์ผ, ์ ํ๋ฒํธ, ์์ด๋, ๋น๋ฐ๋ฒํธ, ์ด๋ฉ์ผ์ ๋ชจ๋ Body์ ๋ด์ ์์ฒญํ ํ,
- ๊ฐ์ ์ด ์๋ฃ๋๋ฉด ๊ฐ์ ์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐํํ๋๋ก ์ค๊ณํ์๋ค.
- ํ์ด์ง ๋ณ๋ก ๊ฐ์ ๋๊ธฐ๋ ๊ฒ์ด ์๋๋ผ, ํ๋ฉด ์ ํํ ๋ ๊ฐ์ ์ ์งํ์ฌ ๋ค์ ๋ทฐ๋ก ๋๊ฒจ์ ํ๊บผ๋ฒ์ ์๋ฒ์ ์์ฒญํ๋ ๋ฐฉ์์ผ๋ก ํ๋ก ํธ์ ํ์๋ฅผ ๋ณด์๋ค.
- ์์ด๋๋ ๊ฐ์ ์์ ์ค๋ณต ํ์ธ์ ๋ฐ๋์ ํ๋๋ก ์ค์ ํ์๊ณ ,
- ์๋ฌธ์ผ๋ก ๋ฐ๋์ ์์, ์ซ์์ ์กฐํฉ๋ 4~20์๋ก ์ ๊ท์์ ์ค์ ํ์๋ค.
- ๋น๋ฐ๋ฒํธ๋ ์๋ฌธ+์ซ์+ํน์๊ธฐํธ 10์ ์ด์ 30์ ์ดํ ์ ์ ๊ท์์ ์ค์ ํ์๊ณ ,
- ์๋ฒ์ ์ ์ฅํ ๋๋ ์ํธํ๋ฅผ ํตํด์ ์ ์ฅํ์๋ค. (SHA 256)
- ์์ด๋๋ ์ฐพ๊ธฐ๊ฐ ๊ฐ๋ฅํ์ง๋ง, ๋น๋ฐ๋ฒํธ๋ ์ฌ์ค์ ์ ํ์ฌ์ผํ๋ค.
(1) ๋ก์ง ํ๋ก์ฐ
1. ์ ์ ์์ด๋/์ด๋ฆ/์์ผ/์ ํ๋ฒํธ/๋น๋ฐ๋ฒํธ/์ด๋ฉ์ผ, ์๋น์ค/๊ฐ์ธ์ ๋ณด/sms/์ด๋ฉ์ผ/์ ํ ์์ ๋์์ ๋ํ ์ ๋ณด๋ฅผ ๋ฐ๋์ ๋ด์ POST์ ์์ฒญ๋ฐ์.
2. ์์ด๋, ๋น๋ฐ๋ฒํธ, ์ด๋ฆ์ ๋ํ ์ ๊ท์ ํ์ธ, ์ฌ๋ฐ๋ฅธ ์๋
์์ผ/์ ํ๋ฒํธ ์์์ธ์ง ์ ๊ท์ ํ์ธ
3. ์ค๋ณต ์์ด๋ ์ฒดํฌ
4. ๋น๋ฐ๋ฒํธ ์ํธํ(SHA256 ๋จ๋ฐฉํฅ ์ํธํ ์๊ณ ๋ฆฌ์ฆ) -> ์ํธํ ๊ด๋ จ ํฌ์คํ
5. ์ ์ ๋ฑ๋ก ํ PK ๋ฐํ
- ์์ฒญ ๋ฐ๋ [PostSignUpReq.java]
- SellerController.java
- ValidationRegx.java
public class ValidationRegex { // ์์ด๋ ์ ๊ท์ - ์์์ ์๋ฌธ์ผ๋ก๋ง, '_'๋ฅผ ์ ์ธํ ํน์๋ฌธ์ ์๋๋ฉฐ ์๋ฌธ, ์ซ์, '_'์ผ๋ก๋ง ์ด๋ฃจ์ด์ง 4 ~ 20์ ์ดํ public static boolean isRegexUid(String target) { String regex = "^[a-zA-Z]{1}[a-zA-Z0-9_]{3,19}$"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(target); return matcher.find(); } // ๋น๋ฐ๋ฒํธ ์ ๊ท์ public static boolean isRegexPassword(String target) { boolean result; //์ต์ 8๊ธ์, ์ต๋16๊ธ์, ๋๋ฌธ์ 1๊ฐ, ์๋ฌธ์ 1๊ฐ, ์ซ์ 1๊ฐ, ํน์๋ฌธ์ 1๊ฐ //String regex = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,16}$"; //์ต๋ 30๊ธ์, ์๋ฌธ์ 1๊ฐ, ์ซ์ 1๊ฐ, ํน์๋ฌธ์ 1๊ฐ : ์๋ฌธ + ์ซ์ + ํน์๊ธฐํธ 8 ์์ด์ String regex1 = "^(?=.*[a-z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,30}$"; //์ต๋ 30๊ธ์ : ์๋ฌธ + ์ซ์ 10์ ์ด์ String regex2 = "^(?=.*[a-zA-z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{10,30}$"; Pattern pattern1 = Pattern.compile(regex1, Pattern.CASE_INSENSITIVE); Pattern pattern2 = Pattern.compile(regex2, Pattern.CASE_INSENSITIVE); Matcher matcher1 = pattern1.matcher(target); Matcher matcher2 = pattern1.matcher(target); //result=target.matches(regex1) || target.matches(regex2); result = matcher1.find() || matcher2.find(); return result; } // ์๋ ์์ผ ์ ๊ท์ yyyy.mm.dd public static boolean isRegexBirth(String target){ String regex = "^\\d{4}\\.\\d{2}\\.\\d{2}$"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(target); return matcher.find(); } // ํธ๋ํฐ ๋ฒํธ ์ ๊ท์ (์ซ์๋ก๋ง ์ด๋ฃจ์ด์ง ์ ํ๋ฒํธ) public static boolean isRegexPhone(String target){ String regex = "^\\d{3}\\d{4}\\d{4}$"; Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(target); return matcher.find(); } }
- SellerService.java
@Transactional(rollbackFor = BaseException.class) public PostSignUpRes signUp(PostSignUpReq postSignUpReq) throws BaseException { String salt; // ์์ด๋, ๋น๋ฐ๋ฒํธ, ๋๋ค์ ์ ๊ท์ ์ฒ๋ฆฌ if(postSignUpReq.getUid().length() == 0 || postSignUpReq.getPassword().length() == 0 || postSignUpReq.getName().length() == 0){ throw new BaseException(REQUEST_ERROR); // 2000 : ์ ๋ ฅ๊ฐ ์ ์ฒด ๋น ๊ฐ์ผ๋ } if(!isRegexUid(postSignUpReq.getUid())){ throw new BaseException(POST_USERS_INVALID_UID); // 2010 : ์์ด๋ ์ ๊ท ํํ์ ์์ธ } if(!isRegexPassword(postSignUpReq.getPassword())){ throw new BaseException(POST_USERS_INVALID_PASSWORD); // 2011 : ๋น๋ฐ๋ฒํธ ์ ๊ท ํํ์ ์์ธ } // ์ฌ๋ฐ๋ฅธ ์๋ ์์ผ ์์์ธ์ง? if(!isRegexBirth(postSignUpReq.getBirthday())){ throw new BaseException(POST_USERS_INVALID_BIRTHDAY); } if(!isRegexPhone(postSignUpReq.getPhone())){ throw new BaseException(POST_USERS_INVALID_PHONENUM); } // ์ค๋ณต ์์ด๋ ์ฒดํฌ if(sellerDao.checkUid(postSignUpReq.getUid()) == 1){ throw new BaseException(POST_USERS_EXISTS_ID); // 2018 : ์ค๋ณต ์์ด๋ } // ๋น๋ฐ๋ฒํธ ์ํธํ try{ salt = SHA256.createSalt(postSignUpReq.getPassword()); // ๋น๋ฐ๋ฒํธ๋ฅผ ์ด์ฉํ์ฌ salt ์์ฑ String pwd = new SHA256().encrypt(postSignUpReq.getPassword(), salt); // ๋น๋ฐ๋ฒํธ ์ํธํ postSignUpReq.setPassword(pwd); } catch (Exception ignored) { throw new BaseException(PASSWORD_ENCRYPTION_ERROR); // 4011 : ๋น๋ฐ๋ฒํธ ์ํธํ์ ์คํจํ์์ต๋๋ค } try{ // ์ ์ ๊ณ ์ ์๋ณ๋ฒํธ int sellerIdx = sellerDao.signUp(postSignUpReq, salt); PostSignUpRes postSignUpres = sellerDao.signUpComplete(sellerIdx); postSignUpres.setCompleteDate(postSignUpres.getCompleteDate().substring(0,10)); return postSignUpres; } catch (Exception exception) { throw new BaseException(SIGNUP_FAILED); } }
- ํ์๊ฐ์ ์์ฒญ์์ ์์ด๋, ๋น๋ฐ๋ฒํธ, ์ด๋ฆ์ ๊ธธ์ด๊ฐ ๋น ๋ฌธ์์ด(๊ธธ์ด๊ฐ 0 ์ธ)์ธ์ง ํ์ธ
- ์์ด๋๊ฐ ์์์ ์๋ฌธ์ผ๋ก๋ง, ''๋ฅผ ์ ์ธํ ํน์๋ฌธ์ ์๋๋ฉฐ ์๋ฌธ, ์ซ์, ''์ผ๋ก๋ง ์ด๋ฃจ์ด์ง 4 ~ 20์ ์ดํ ๋ฅผ ๋ง์กฑํ๋์ง ์ ๊ท์ ํ์ธ
- ๋น๋ฐ๋ฒํธ๊ฐ ์ต๋ 30๊ธ์, ์๋ฌธ์ 1๊ฐ, ์ซ์ 1๊ฐ, ํน์๋ฌธ์ 1๊ฐ : ์๋ฌธ + ์ซ์ + ํน์๊ธฐํธ 8 ์์ด์ ๋๋ ์๋ฌธ + ์ซ์ 10์ ์ด์ ๋ฅผ ๋ง์กฑํ๋์ง ์ ๊ท์ ํ์ธ
- ์ฌ๋ฐ๋ฅธ ์๋ ์์ผ ์์ (yyyy.mm.dd) ์ ๋ง์กฑํ๋์ง ์ ๊ท์ ํ์ธ
- ์ฌ๋ฐ๋ฅธ ํธ๋ํฐ ๋ฒํธ ์์ (์ซ์๋ก๋ง ์ด๋ค์ง 10๊ธ์ ํด๋๋ฒํธ)๋ฅผ ๋ง์กฑํ๋์ง ์ ๊ท์ ํ์ธ
- ์์ด๋๊ฐ ์ค๋ณต๋๋์ง DB๋ฅผ ์กฐํํ์ฌ ํ์ธ -> ์์ด๋ ์ค๋ณต์ ์์ธ ์ฒ๋ฆฌ
- ๋น๋ฐ๋ฒํธ ์ํธํ (SHA 256)์ ์ด์ฉํ์ฌ ์ ๋ ฅ๋ฐ์ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ณ๊ฒฝ -> ๋น๋ฐ๋ฒํธ ์ํธํ ํฌ์คํ
- ์ํธํ ์ฑ๊ณต ํ, ์ ์ ํ์๊ฐ์ ์ ๋ณด๋ฅผ DB์ ์ ์ฅ, ์ ์ PK DB์์ ํ์ธ
- ๊ฐ ์ฝ์ ํ ์์ฑ๋ PK๋ก ๋ค์ ์กฐํํ์ฌ ํ์์ ๋ณด๋ฅผ ๋ฐํํ ์ค๋น
- ์ ์ ์๊ฒ ๋ณด์ฌ์ง ํ์ ๊ฐ์ ์ ๋ณด๋ฅผ Response
SellerDao.java
- ์์ด๋ ์ค๋ณต ์ฒดํฌ
- ์ ํจํ ํ๋งค์ ํ์ ์ ๋ณด ์ค (status = 'A') ์์ด๋๊ฐ ์ ๋ ฅ๋ ๊ฒ์ด ์กด์ฌํ๋์ง ํ์ธ.public int checkUid(String uid) { String query = "SELECT EXISTS(SELECT sellerIdx FROM Merchandisers WHERE uid = ? and status = 'A')"; return this.jdbcTemplate.queryForObject(query, int.class, uid); }
- ํ์ ์ ๋ณด Merchandisers(ํ๋งค์) ํ ์ด๋ธ์ ์ฝ์
public int signUp(PostSignUpReq postSignUpReq, String salt){ String query = "INSERT INTO Merchandisers(name, birthday, phone, uid, salt, password, email, first_login, service_check, personal_check, sms_check, email_check, call_check, role)\n" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"; Object[] params = new Object[]{ postSignUpReq.getName(), postSignUpReq.getBirthday(), postSignUpReq.getPhone(), postSignUpReq.getUid(), salt, // ๋น๋ฐ๋ฒํธ ์ํธํ์ ์ฌ์ฉ๋๋ ์ถ๊ฐ ๋ฌธ์์ด postSignUpReq.getPassword(), postSignUpReq.getEmail(), 1, // ์ต์ด ๋ก๊ทธ์ธ ์ฌ๋ถ (1=์ต์ด ๋ก๊ทธ์ธ, 0=ํ๋ฒ ์ด์์ ๋ก๊ทธ์ธ) postSignUpReq.getServiceCheck(), postSignUpReq.getPersonalCheck(), postSignUpReq.getSmsCheck(), postSignUpReq.getEmailCheck(), postSignUpReq.getCallCheck(), "ROLE_SELLER" // Security ์ธ๊ฐ์ ์ฌ์ฉ๋๋ ์ญํ }; this.jdbcTemplate.update(query, params); String lastInsertIdQuery = "select last_insert_id()"; return this.jdbcTemplate.queryForObject(lastInsertIdQuery,int.class); }
- ํ์๊ฐ์ ์์ ๋ณด๋๋ ์์ด๋, ๋น๋ฐ๋ฒํธ๋ฅผ ์๋ฒ์ ์์ฒญํ๋ฉด,
- ์๋ฒ์์ ๋ก์ง ์ฒ๋ฆฌ ํ ํด๋น ๊ฐ์ ์ ๋ณด์ ๊ธฐ๋ณธ ๊ฐ๋ค๊ณผ JWT ์ธ๊ฐ ํ ํฐ์ ๋ฐํํ์ฌ ํด๋ผ์ด์ธํธ์๊ฒ Response
- ๋ฐํ๋ ์ด JWT ํ ํฐ์ ๋ก๊ทธ์ธ ํ์ ์์ฒญํ๋ ๋ชจ๋ API์ ํค๋์ ๋ด์์ ๋ณด๋ด์ผ ํ๋ค.
(1) ๋ก์ง ํ๋ก์ฐ
1. ๊ฐ์
๋ ์์ด๋/ ๋น๋ฐ๋ฒํธ๋ฅผ ๋ฐ๋์ ๋ด์์ POST๋ก ์์ฒญ์ ๋ณด๋ธ๋ค.
2. ์์ด๋, ๋น๋ฐ๋ฒํธ์ ๊ธธ์ด๊ฐ 0 (๋น ๊ฐ)์ผ๋ก ๋ณด๋ด์ก๋์ง ํ์ธ
3. ์์ด๋๋ฅผ ๊ฐ์ง๊ณ ๊ฐ์
๋ ์ ๋ณด๋ฅผ ๋ชจ๋ DB์์ ๊ฐ์ ธ์ด
4. ๊ฐ์
๋ ์ ๋ณด๊ฐ ์กด์ฌํ๋ค๋ฉด, ํด๋น ํ๋งค์ ๊ณ์ ์ ๊ฐ๊ฒ ์๋น์ค๊ฐ ๋ฑ๋ก๋์ด ์๋์ง ํ์ธ
5. ๊ฐ๊ฒ ์๋น์ค -> ๋ณธ์ธ์ ํ๋งค์ ๋ฑ๋ก, ํ๋งค์ ์ ๋ฉ๋ด ๋ฑ๋ก ์ด ๋ชจ๋ ์๋ฃ๋์๋์ง ํ์ธ ํ์ฌ ํ๋ก ํธ์์ ๋ณด์ฌ์ค ํ๋ฉด์ ์๋ณํ ์ ์๋ ๊ฐ์ ๋ฐํํ๋ค.
6. DB์ ์กด์ฌํ๋ ์ํธํ๋ ๋น๋ฐ๋ฒํธ์ ์
๋ ฅ๋ ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํํ์ฌ ๋น๊ตํ์ ๋ ์ผ์นํ๋ค๋ฉด, ๋ก๊ทธ์ธ ์ฑ๊ณต
7. ๋ก๊ทธ์ธ ์ฑ๊ณต ์ ์ ์ ๊ฐ ์๋น์ค๋ฅผ ์ด์ฉํ๊ธฐ ์ํด ์ฌ์ฉํ JWTํ ํฐ์ ๋ฐํํ์ฌ Response
-> JWT๊ด๋ จ ํฌ์คํ
-> ์ํธํ ๊ด๋ จ ํฌ์คํ
- ์์ฒญ ๋ฐ๋ [PostSignUpReq.java]
- SellerController.java
- SellerService.java
@Transactional(rollbackFor = BaseException.class) public PostLoginRes login(PostLoginReq postLoginReq) throws BaseException{ if(postLoginReq.getUid().length() == 0 || postLoginReq.getPassword().length() == 0){ throw new BaseException(REQUEST_ERROR); // 2000 : ์ ๋ ฅ๊ฐ ์ ์ฒด ๋น ๊ฐ์ผ๋ } // 1) ์์ด๋๊ฐ ์กด์ฌํ๋์ง ํ์ธ, ํ์์ ๋ณด ์ฐ์ ์กฐํ Seller seller; try{ seller = sellerDao.login(postLoginReq); }catch(Exception exception){ throw new BaseException(FAILED_TO_LOGIN); } // 1-2) ์ ๊ฐ๊ฒ ๋ฑ๋ก ์ฌ๋ถ ์กด์ฌํ์ธ int storeRegistered = 0; try{ storeRegistered = storeDao.storeIdxBySellerIdxExists(seller.getSellerIdx()); }catch(Exception exception){ throw new BaseException(FAILED_TO_LOGIN); } // 2) ํ์๊ฐ์ ํ ๊ฐ๊ฒ์น์ธ ๋ฐ ๋ฉ๋ด ๋ฑ๋ก ์ฌ๋ถ ํ์ธ StoreNameNStatus storeNameStatus = null; try{ if (storeRegistered == 1){ // storeName from storeDao storeNameStatus = storeDao.storeNameBySellerIdx(seller.getSellerIdx()); } }catch(Exception exception){ throw new BaseException(FAILED_TO_LOGIN); } // 3) ๋น๋ฐ ๋ฒํธ ์ํธํ try{ String salt = seller.getSalt(); String pwd = new SHA256().encrypt(postLoginReq.getPassword(), salt); if (postLoginReq.getUid().equals(seller.getUid()) && pwd.equals(seller.getPassword())){ String jwt = jwtTokenProvider.createJwt(seller.getSellerIdx(), "Merchandiser"); return new PostLoginRes(jwt, seller.getSellerIdx(), seller.getName(), seller.getFirst_login(), seller.getMenu_register(), storeNameStatus != null ? storeNameStatus.getStore_name() : "", // null ์ด ์๋๊ฒ์ ๊ฐ๊ฒ๋ฑ๋ก์ ๋ฌด์กฐ๊ฑด ํ๋ค๋๊ฒ. storeNameStatus != null ? storeNameStatus.getStore_status() : null); // null } else{ throw new BaseException(FAILED_TO_LOGIN); } }catch(Exception exception){ throw new BaseException(FAILED_TO_LOGIN); } }
- 3) ๋น๋ฐ ๋ฒํธ ์ํธํ ๋ถ๋ถ์์ jwt๋ฅผ ๋ง๋๋ ํจ์์ ํ๋งค์ PK๊ฐ๊ณผ "Merchandiser"์ด๋ผ๋ ๋งค๊ฐ๋ณ์๊ฐ ๋ค์ด๊ฐ๋ค.
- ์ด๋ ํ๋งค์์ ๊ตฌ๋งค์์ DB ํ ์ด๋ธ์ด ๋ฌ๋ผ์ SpringSecurit Filter์์ ํค๋๋ด์ ์กด์ฌํ๋ jwtํ ํฐ ๊ฐ์ ์ด์ฉํด userIdx ๊ธฐ๋ณธํค๋ก ์กฐํ๋ฅผ ํ ๋ ์ด๋ค ํ ์ด๋ธ์ ์ฐธ์กฐํ ์ง,
- ์ฆ ์ ์ ์กฐํ๋ฅผ ๊ตฌ๋งค์ ํ ์ด๋ธ, ํ๋งค์ ํ ์ด๋ธ ๋ ์ค ์ด๋์ ํ ์ง ๊ตฌ๋ณํ๊ธฐ ์ํ ๊ฐ์ด๋ค.
- ๊ตฌ๋งค์ ๊ฐ์๊ฒฝ์ฐ ํด๋น ๋ถ๋ถ์ "Customer"์ด๋ผ๊ณ ๋งค๊ฐ๋ณ์๊ฐ ๋ค์ต๋๋ค.
- SellerDao.java
// ID๋ฅผ ์ด์ฉํ ๋ก๊ทธ์ธ ์ ๋ณด ๋ฐํ public Seller login(PostLoginReq postLoginReq) { String query = "SELECT * FROM Merchandisers WHERE uid = ?"; return this.jdbcTemplate.queryForObject(query, (rs, rowNum) -> new Seller( rs.getInt("sellerIdx"), rs.getString("name"), rs.getString("birthday"), rs.getString("phone"), rs.getString("uid"), rs.getString("salt"), rs.getString("password"), rs.getString("email"), rs.getInt("first_login"), rs.getInt("menu_register"), null ), postLoginReq.getUid()); }
// ๊ฐ๊ฒ๋ฑ๋ก ์ฌ๋ถ ํ์ธ public int storeIdxBySellerIdxExists(int sellerIdx){ String query = "SELECT EXISTS(SELECT storeIdx FROM Stores WHERE sellerIdx = ?)"; return this.jdbcTemplate.queryForObject(query, int.class, sellerIdx); }
// ๊ฐ๊ฒ๋ฑ๋ก ํ๋ค๋ฉด ํ์ฌ ์ํ ๋ฐํ(๊ด๋ฆฌ์ ์น์ธ ๊ธฐ๋ค๋ฆฌ๊ณ ์๋์ง?, ๋ฉ๋ด ๋ฑ๋กํ๋์ง?) public StoreNameNStatus storeNameBySellerIdx(int sellerIdx){ String query = "SELECT store_name, status FROM Stores WHERE sellerIdx = ?"; return this.jdbcTemplate.queryForObject(query, (rs, rowNum) -> new StoreNameNStatus( rs.getString("store_name"), rs.getString("status") ), sellerIdx); }