Skip to content

Commit

Permalink
Merge pull request #11 from ssafy-19-final-pjt/feature/#1-oauth-login
Browse files Browse the repository at this point in the history
Feature/#1 oauth login
  • Loading branch information
gurwls0122 authored May 20, 2024
2 parents 67f9573 + a0b654a commit 62ea24b
Show file tree
Hide file tree
Showing 14 changed files with 287 additions and 91 deletions.
5 changes: 4 additions & 1 deletion backend/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ dependencies {
compileOnly 'org.projectlombok:lombok:'
annotationProcessor 'org.projectlombok:lombok'

testImplementation 'org.springframework.boot:spring-boot-starter-test'
//mysql
runtimeOnly 'com.mysql:mysql-connector-j'

Expand Down Expand Up @@ -62,6 +61,10 @@ dependencies {

// 이메일 전송 (비밀번호 찾기)
implementation 'org.springframework.boot:spring-boot-starter-mail'

// test 환경에서는 h2 사용
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testRuntimeOnly 'com.h2database:h2'
}

dependencyManagement {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.jpa.repository.config.EnableJpaAuditing;
import org.springframework.scheduling.annotation.EnableScheduling;

@EnableJpaAuditing
@SpringBootApplication
@EnableScheduling
public class WhereIsMyHomeApplication {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

import com.ssafy.home.domain.member.dto.request.FindPasswordRequest;
import com.ssafy.home.domain.member.dto.request.LoginRequest;
import com.ssafy.home.domain.member.dto.request.UpdatePasswordRequest;
import com.ssafy.home.domain.member.dto.request.RegisterRequest;
import com.ssafy.home.domain.member.dto.request.UpdatePasswordRequest;
import com.ssafy.home.domain.member.dto.response.TokenResponse;
import com.ssafy.home.domain.member.repository.MemberRepository;
import com.ssafy.home.domain.member.service.MemberService;
import com.ssafy.home.global.auth.dto.MemberDto;
import com.ssafy.home.global.auth.jwt.JwtTokenProvider;
Expand All @@ -26,15 +25,13 @@

import java.util.Arrays;

@Tag(name = "member", description = "회원 API")
@RestController
@RequestMapping("/member")
@RequiredArgsConstructor
public class MemberController {

private final MemberService memberService;
private final RefreshTokenValidator refreshTokenValidator;
private final MemberRepository memberRepository;

@Tag(name = "authentication")
@Operation(summary = "일반 회원가입 API", description = "일반 회원가입 API")
Expand Down Expand Up @@ -87,7 +84,7 @@ public ResponseEntity<String> createAccessToken(HttpServletRequest request, Http

response.addHeader(JwtTokenProvider.AUTHORIZATION_HEADER, memberService.reissue(refreshToken));

return ResponseEntity.status(HttpStatus.OK).body("access token");
return ResponseEntity.status(HttpStatus.OK).body("access token success");
}

@Tag(name = "authentication")
Expand Down Expand Up @@ -130,7 +127,7 @@ public ResponseEntity<String> findPassword(@RequestBody FindPasswordRequest find
@Tag(name = "authentication")
@Operation(summary = "유저 정보 가져오기 API", description = "유저 정보 가져오기 API")
@PostMapping("/info")
public ResponseEntity<MemberDto> findPassword(@AuthenticationPrincipal MemberDto memberDto){
public ResponseEntity<MemberDto> getMemberInfo(@AuthenticationPrincipal MemberDto memberDto){

return ResponseEntity.status(HttpStatus.OK).body(memberDto);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ssafy.home.domain.member.dto.request;

import com.ssafy.home.entity.member.Member;
import lombok.Getter;
import lombok.NoArgsConstructor;

Expand All @@ -10,11 +9,4 @@ public class RegisterRequest {
private String name;
private String email;
private String password;

public Member toEntity(){
return Member.builder()
.name(name)
.email(email)
.build();
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
import com.ssafy.home.entity.member.Member;
import com.ssafy.home.entity.member.MemberSecret;
import com.ssafy.home.global.auth.Encryption;
import com.ssafy.home.global.auth.constant.EmailConstraints;
import com.ssafy.home.global.auth.jwt.JwtTokenProvider;
import com.ssafy.home.global.auth.util.SendEmailLogic;
import com.ssafy.home.global.error.ErrorCode;
import com.ssafy.home.global.error.exception.AuthenticationException;
import com.ssafy.home.global.error.exception.BusinessException;
Expand All @@ -23,8 +25,6 @@
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

@Service
@RequiredArgsConstructor
Expand All @@ -37,15 +37,15 @@ public class MemberService {
private final LoginAttemptRepository loginAttemptRepository;

private final JavaMailSender javaMailSender;
private final SpringTemplateEngine templateEngine;
private final JwtTokenProvider jwtTokenProvider;
private final Encryption encryption;
private final SendEmailLogic sendEmailLogic;

@Transactional
public void register(String email, String password, String name) {

if (memberRepository.existsByEmail(email)) {
throw new AuthenticationException(ErrorCode.MEMBER_NOT_MATCH);
throw new AuthenticationException(ErrorCode.ALREADY_REGISTERED_MEMBER);
}

String salt = encryption.getSalt();
Expand All @@ -58,11 +58,15 @@ public void register(String email, String password, String name) {

Member member = memberRepository.save(Member.builder()
.name(name)
.email(email)
.build());
GeneralMember generalMember = generalMemberRepository.save(GeneralMember.builder().member(member).userEncPassword(password).build());
memberSecurityRepository.save(MemberSecret.builder().generalMember(generalMember).salt(salt).build());
loginAttemptRepository.save(LoginAttempt.builder().member(member).build());
.email(email).build());
GeneralMember generalMember = generalMemberRepository.save(GeneralMember.builder()
.member(member)
.userEncPassword(password).build());
memberSecurityRepository.save(MemberSecret.builder()
.generalMember(generalMember)
.salt(salt).build());
loginAttemptRepository.save(LoginAttempt.builder()
.member(member).build());
}

@Transactional
Expand Down Expand Up @@ -99,7 +103,7 @@ public TokenResponse login(String email, String password) {

} catch (AuthenticationException e){
member.getLoginAttempt().updateCount();
throw new AuthenticationException(e.getErrorCode());
throw new AuthenticationException(ErrorCode.MEMBER_NOT_MATCH);
} catch (Exception e) {
member.getLoginAttempt().updateCount();
e.printStackTrace();
Expand Down Expand Up @@ -149,15 +153,13 @@ public void updatePassword(Long id, String password) {
member.getGeneralMember().updatePassword(encPassword);
}

private final String MAIL_TITLE = "where-is-my-home의 비밀번호 변경 이메일 입니다.";

@Transactional
@Async("mailExecutor")
public void sendPassword(String email) {

Member member = memberRepository.findByEmail(email).orElseThrow(() -> new AuthenticationException(ErrorCode.MEMBER_NOT_MATCH));

String newPassword = makeRandomPassword();
String newPassword = sendEmailLogic.makeRandomPassword();

try {
String encPassword = encryption.Hashing(newPassword.getBytes(),member.getGeneralMember().getMemberSecret().getSalt());
Expand All @@ -171,34 +173,19 @@ public void sendPassword(String email) {
try {
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, false, "UTF-8");
mimeMessageHelper.setTo(email); // 메일 수신자
mimeMessageHelper.setSubject(MAIL_TITLE); // 메일 제목
mimeMessageHelper.setText(setContext(newPassword, "password"), true); // 메일 본문 내용, HTML 여부
mimeMessageHelper.setSubject(EmailConstraints.MAIL_TITLE); // 메일 제목
mimeMessageHelper.setText(sendEmailLogic.setContext(newPassword, "password"), true); // 메일 본문 내용, HTML 여부
javaMailSender.send(mimeMessage);

} catch (MessagingException e) {
throw new BusinessException(ErrorCode.EMAIL_FAIL);
}
}


static char[] charSet = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

private String makeRandomPassword(){

StringBuilder pw = new StringBuilder();

for (int i = 0; i < 10; i++) {
int idx = (int) (charSet.length * Math.random());
pw.append(charSet[idx]);
}

return String.valueOf(pw);
}

public String setContext(String code, String type) {
Context context = new Context();
context.setVariable("code", code);
return templateEngine.process(type, context);
@Transactional
public void initAttempt(){
loginAttemptRepository.findAll().stream()
.filter(loginAttempt -> loginAttempt.getCount() >= 5)
.forEach(LoginAttempt::initCount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.ssafy.home.global.auth.constant;

public final class EmailConstraints {
// Util로 빼기 constant 로 넘기기 (상수
public static final String MAIL_TITLE = "where-is-my-home의 비밀번호 변경 이메일 입니다.";

public static final char[] charSet = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F',
'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.ssafy.home.global.auth.util;

import com.ssafy.home.global.auth.constant.EmailConstraints;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.thymeleaf.context.Context;
import org.thymeleaf.spring6.SpringTemplateEngine;

@Service
@RequiredArgsConstructor
public class SendEmailLogic {

private final SpringTemplateEngine templateEngine;

public String makeRandomPassword(){

StringBuilder pw = new StringBuilder();

for (int i = 0; i < 10; i++) {
int idx = (int) (EmailConstraints.charSet.length * Math.random());
pw.append(EmailConstraints.charSet[idx]);
}

return String.valueOf(pw);
}

public String setContext(String code, String type) {
Context context = new Context();
context.setVariable("code", code);
return templateEngine.process(type, context);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.ssafy.home.global.config.batch;

import com.ssafy.home.domain.member.service.MemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
@Slf4j
@RequiredArgsConstructor
public class ScheduledJobConfiguration {
private final MemberService memberService;

@Scheduled(cron ="0 30 * * * *", zone = "Asia/Seoul")
public void scheduledEndForm() {
memberService.initAttempt();
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.ssafy.home.global.config.security;

import com.ssafy.home.domain.member.repository.MemberRepository;
import com.ssafy.home.domain.member.service.MemberService;
import com.ssafy.home.global.auth.filter.JwtAuthenticationFilter;
import com.ssafy.home.global.auth.interceptor.UserActivationInterceptor;
Expand All @@ -22,7 +21,6 @@
@RequiredArgsConstructor
@EnableWebSecurity(debug = true)
public class WebSecurityConfiguration implements WebMvcConfigurer {
private final MemberRepository memberRepository;
private final JwtTokenProvider jwtTokenProvider;
private final MemberService memberService;

Expand Down
22 changes: 22 additions & 0 deletions backend/src/main/resources/application-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
spring:
sql:
init:
mode: always

datasource:
url: jdbc:h2:mem:test
driverClassName: org.h2.Driver
username: sa
password:

jpa:
hibernate:
ddl-auto: create-drop
database-platform: org.hibernate.dialect.H2Dialect
show-sql: true
properties:
hibernate:
format_sql: true
#데이터베이스 초기화를 지연시키는 옵션. true 로 설정을하면 애플리케이션이 실행될 때 db를 초기화하지 않고 첫 데이터베이스 액세스 시 초기화를 수행(data.sql문 실행)한다.
defer-datasource-initialization: true
generate-ddl: true
11 changes: 11 additions & 0 deletions backend/src/main/resources/data.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
INSERT INTO member (create_date, email, is_deleted, modify_date, name, profile, refresh_token, id)
VALUES (TIMESTAMP '2024-05-19 00:00:00', '[email protected]', false, TIMESTAMP '2024-05-19 00:00:00', 'test', NULL, '', 11);

INSERT INTO general_member (member_id, user_enc_password, id)
VALUES (11, '2492b60365ec438c50a4b37302790e61000eaf6866338c4f39d5d7c1cfdd4b78', 11);

INSERT INTO member_secret (member_id, salt, id)
VALUES (11, '7b6fcbe49833ef658d3f87e2cec1b83c', DEFAULT);

INSERT INTO login_attempt (count, login_recent_attemp, member_id, id)
VALUES (0, TIMESTAMP '2024-05-19 00:00:00', 11, DEFAULT);
Loading

0 comments on commit 62ea24b

Please sign in to comment.