Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

๐Ÿ›[Fix] refresh Token ๋ฐœ๊ธ‰ ์‹œ ํšŒ์› ์ •๋ณด ์ˆ˜์ • ๋‚ ์งœ ์—…๋ฐ์ดํŠธ ๋˜๋Š”๊ฑฐ ์ˆ˜์ • #318

Merged
merged 1 commit into from
Nov 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions src/main/generated/com/gamegoo/domain/member/QMember.java
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,6 @@ public class QMember extends EntityPathBase<Member> {

public final NumberPath<Integer> rank = createNumber("rank", Integer.class);

public final StringPath refreshToken = createString("refreshToken");

public final ListPath<com.gamegoo.domain.report.Report, com.gamegoo.domain.report.QReport> reportList = this.<com.gamegoo.domain.report.Report, com.gamegoo.domain.report.QReport>createList("reportList", com.gamegoo.domain.report.Report.class, com.gamegoo.domain.report.QReport.class, PathInits.DIRECT2);

public final NumberPath<Integer> subPosition = createNumber("subPosition", Integer.class);
Expand Down
61 changes: 61 additions & 0 deletions src/main/generated/com/gamegoo/domain/member/QRefreshToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.gamegoo.domain.member;

import static com.querydsl.core.types.PathMetadataFactory.*;

import com.querydsl.core.types.dsl.*;

import com.querydsl.core.types.PathMetadata;
import javax.annotation.processing.Generated;
import com.querydsl.core.types.Path;
import com.querydsl.core.types.dsl.PathInits;


/**
* QRefreshToken is a Querydsl query type for RefreshToken
*/
@Generated("com.querydsl.codegen.DefaultEntitySerializer")
public class QRefreshToken extends EntityPathBase<RefreshToken> {

private static final long serialVersionUID = -263126930L;

private static final PathInits INITS = PathInits.DIRECT2;

public static final QRefreshToken refreshToken1 = new QRefreshToken("refreshToken1");

public final com.gamegoo.domain.common.QBaseDateTimeEntity _super = new com.gamegoo.domain.common.QBaseDateTimeEntity(this);

//inherited
public final DateTimePath<java.time.LocalDateTime> createdAt = _super.createdAt;

public final NumberPath<Long> id = createNumber("id", Long.class);

public final QMember member;

public final StringPath refreshToken = createString("refreshToken");

//inherited
public final DateTimePath<java.time.LocalDateTime> updatedAt = _super.updatedAt;

public QRefreshToken(String variable) {
this(RefreshToken.class, forVariable(variable), INITS);
}

public QRefreshToken(Path<? extends RefreshToken> path) {
this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS));
}

public QRefreshToken(PathMetadata metadata) {
this(metadata, PathInits.getFor(metadata, INITS));
}

public QRefreshToken(PathMetadata metadata, PathInits inits) {
this(RefreshToken.class, metadata, inits);
}

public QRefreshToken(Class<? extends RefreshToken> type, PathMetadata metadata, PathInits inits) {
super(type, metadata, inits);
this.member = inits.isInitialized("member") ? new QMember(forProperty("member")) : null;
}

}

Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public enum ErrorStatus implements BaseErrorCode {
TOKEN_EXPIRED(HttpStatus.UNAUTHORIZED, "JWT400", "jwt ํ† ํฐ์ด ๋งŒ๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค."),
INVALID_TOKEN(HttpStatus.BAD_REQUEST, "JWT401", "์œ ํšจํ•˜์ง€ ์•Š์€ jwt ํ† ํฐ์ž…๋‹ˆ๋‹ค."),
TOKEN_NULL(HttpStatus.NOT_FOUND, "JWT402", "JWT ํ† ํฐ์ด ์—†์Šต๋‹ˆ๋‹ค."),
REFRESHTOKEN_NULL(HttpStatus.NOT_FOUND,"JWT403","Refresh Token์ด ์—†์Šต๋‹ˆ๋‹ค."),
REFRESHTOKEN_NULL(HttpStatus.NOT_FOUND,"JWT403","Refresh Token์ด ํ‹€๋ ธ์Šต๋‹ˆ๋‹ค."),
// GameStyle ๊ด€๋ จ ์—๋Ÿฌ
GAMESTYLE_NOT_FOUND(HttpStatus.NOT_FOUND, "GAMESTYLE400", "ํ•ด๋‹น ๊ฒŒ์ž„ ์Šคํƒ€์ผ์„ ์ฐพ์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค."),

Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/gamegoo/config/SecurityConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.gamegoo.filter.LoggingFilter;
import com.gamegoo.filter.LoginFilter;
import com.gamegoo.repository.member.MemberRepository;
import com.gamegoo.repository.member.RefreshTokenRepository;
import com.gamegoo.security.CustomUserDetailService;
import com.gamegoo.util.JWTUtil;
import java.util.Arrays;
Expand Down Expand Up @@ -36,6 +37,7 @@ public class SecurityConfig {
private final JWTUtil jwtUtil;
private final CustomUserDetailService customUserDetailService;
private final MemberRepository memberRepository;
private final RefreshTokenRepository refreshTokenRepository;

@Bean
public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration)
Expand Down Expand Up @@ -80,7 +82,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.addFilterAfter(new LoggingFilter(jwtUtil), JWTExceptionHandlerFilter.class)
.addFilterAt(
new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil,
memberRepository), UsernamePasswordAuthenticationFilter.class)
memberRepository, refreshTokenRepository), UsernamePasswordAuthenticationFilter.class)
.addFilterBefore(jwtFilter(), LoginFilter.class)
.sessionManagement((session) -> session
.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/com/gamegoo/domain/member/Member.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,6 @@ public class Member extends BaseDateTimeEntity {
@Column(name = "want_position")
private Integer wantPosition = 0;

@Column(name = "refresh_token")
private String refreshToken;

@Column(name = "mike")
private Boolean mike = false;

Expand Down Expand Up @@ -164,10 +161,6 @@ public void updatePassword(String password) {
this.password = password;
}

public void updateRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}

public void setMannerScore(int mannerScore) { this.mannerScore = mannerScore; }
public void setMannerLevel(int mannerLevel) {
this.mannerLevel = mannerLevel;
Expand Down
30 changes: 30 additions & 0 deletions src/main/java/com/gamegoo/domain/member/RefreshToken.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.gamegoo.domain.member;

import com.gamegoo.domain.common.BaseDateTimeEntity;
import lombok.*;

import javax.persistence.*;

@Entity
@Table(name = "RefreshToken")
@Getter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
public class RefreshToken extends BaseDateTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="refresh_token_id")
private Long id;

@Column(name = "refresh_token")
private String refreshToken;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "member_id", nullable = false)
private Member member;

public void updateRefreshToken(String refreshToken){
this.refreshToken = refreshToken;
}
}
23 changes: 18 additions & 5 deletions src/main/java/com/gamegoo/filter/LoginFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import com.gamegoo.apiPayload.ApiResponse;
import com.gamegoo.apiPayload.code.status.ErrorStatus;
import com.gamegoo.domain.member.Member;
import com.gamegoo.domain.member.RefreshToken;
import com.gamegoo.dto.member.MemberResponse;
import com.gamegoo.repository.member.MemberRepository;
import com.gamegoo.repository.member.RefreshTokenRepository;
import com.gamegoo.security.CustomUserDetails;
import com.gamegoo.util.JWTUtil;
import java.io.IOException;
Expand All @@ -31,12 +33,14 @@ public class LoginFilter extends UsernamePasswordAuthenticationFilter {
private final AuthenticationManager authenticationManager;
private final JWTUtil jwtUtil;
private final MemberRepository memberRepository;
private final RefreshTokenRepository refreshTokenRepository;

public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil,
MemberRepository memberRepository) {
MemberRepository memberRepository, RefreshTokenRepository refreshTokenRepository) {
this.authenticationManager = authenticationManager;
this.jwtUtil = jwtUtil;
this.memberRepository = memberRepository;
this.refreshTokenRepository = refreshTokenRepository;
this.setRequiresAuthenticationRequestMatcher(
new AntPathRequestMatcher("/v1/member/login", "POST"));
this.setUsernameParameter("email");
Expand Down Expand Up @@ -77,11 +81,20 @@ protected void successfulAuthentication(HttpServletRequest request,
String access_token = jwtUtil.createJwtWithId(id, 60 * 60 * 1000L); // 1์‹œ๊ฐ„
String refresh_token = jwtUtil.createJwt(60 * 60 * 24 * 30 * 1000L); // 30์ผ

// refresh token DB์— ์ €์žฅํ•˜๊ธฐ
Member member = memberRepository.findById(id)
.orElseThrow();
member.updateRefreshToken(refresh_token);
memberRepository.save(member);
.orElseThrow();

// ์ด์ „์— ์žˆ๋˜ refreshToken ์ „๋ถ€ ์ง€์šฐ๊ธฐ
refreshTokenRepository.findByMember(member).stream()
.forEach(refreshTokenRepository::delete);

// refresh token DB์— ์ €์žฅํ•˜๊ธฐ
RefreshToken newRefreshToken = RefreshToken.builder()
.member(member)
.refreshToken(refresh_token)
.build();

refreshTokenRepository.save(newRefreshToken);

// ํ•ด๋‹น ์œ ์ € ์ด๋ฆ„ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ
String gameuserName = member.getGameName();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ public interface MemberRepository extends JpaRepository<Member, Long> {

Optional<Member> findById(Long id);

Optional<Member> findByRefreshToken(String refresh_token);

@Query("SELECT m FROM Member m INNER JOIN Block b ON m.id = b.blockedMember.id WHERE b.blockerMember.id = :blockerId AND b.isDeleted = false ORDER BY b.createdAt DESC")
Page<Member> findBlockedMembersByBlockerIdAndNotDeleted(@Param("blockerId") Long blockerId,
Pageable pageable);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.gamegoo.repository.member;

import com.gamegoo.domain.member.Member;
import com.gamegoo.domain.member.RefreshToken;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface RefreshTokenRepository extends JpaRepository<RefreshToken,Long> {
Optional<RefreshToken> findByMember(Member member);

Optional<RefreshToken> findByRefreshToken(String refreshToken);
}
23 changes: 13 additions & 10 deletions src/main/java/com/gamegoo/service/member/AuthService.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,9 @@
import com.gamegoo.domain.champion.MemberChampion;
import com.gamegoo.domain.member.LoginType;
import com.gamegoo.domain.member.Member;
import com.gamegoo.domain.member.RefreshToken;
import com.gamegoo.dto.member.MemberResponse;
import com.gamegoo.repository.member.ChampionRepository;
import com.gamegoo.repository.member.EmailVerifyRecordRepository;
import com.gamegoo.repository.member.MemberChampionRepository;
import com.gamegoo.repository.member.MemberRepository;
import com.gamegoo.repository.member.*;
import com.gamegoo.util.CodeGeneratorUtil;
import com.gamegoo.util.JWTUtil;
import com.gamegoo.util.RiotUtil;
Expand Down Expand Up @@ -39,6 +37,7 @@ public class AuthService {
private final ChampionRepository championRepository;
private final MemberChampionRepository memberChampionRepository;
private final EmailVerifyRecordRepository emailVerifyRecordRepository;
private final RefreshTokenRepository refreshTokenRepository;
private final BCryptPasswordEncoder bCryptPasswordEncoder;
private final JavaMailSender javaMailSender;
private final JWTUtil jwtUtil;
Expand Down Expand Up @@ -201,8 +200,10 @@ public void sendEmailVerification(String email) {
@Transactional
public MemberResponse.RefreshTokenResponseDTO verifyRefreshToken(String refresh_token) {
// refresh Token ๊ฒ€์ฆํ•˜๊ธฐ
Member member = memberRepository.findByRefreshToken(refresh_token)
.orElseThrow(() -> new MemberHandler(ErrorStatus.REFRESHTOKEN_NULL));
RefreshToken refreshToken = refreshTokenRepository.findByRefreshToken(refresh_token)
.orElseThrow(() -> new MemberHandler(ErrorStatus.REFRESHTOKEN_NULL));

Member member = refreshToken.getMember();

// refresh ํ† ํฐ์—์„œ id ๊ฐ€์ ธ์˜ค๊ธฐ
Long id = member.getId();
Expand All @@ -212,8 +213,8 @@ public MemberResponse.RefreshTokenResponseDTO verifyRefreshToken(String refresh_
String new_refresh_token = jwtUtil.createJwt(60 * 60 * 24 * 30 * 1000L); // 30์ผ

// refresh token ์ €์žฅํ•˜๊ธฐ
member.updateRefreshToken(new_refresh_token);
memberRepository.save(member);
refreshToken.updateRefreshToken(new_refresh_token);
refreshTokenRepository.save(refreshToken);

return new MemberResponse.RefreshTokenResponseDTO(id, access_token, new_refresh_token);
}
Expand Down Expand Up @@ -442,8 +443,10 @@ public void deleteRefreshToken(Long id) {
Member member = memberRepository.findById(id)
.orElseThrow(() -> new MemberHandler(ErrorStatus.MEMBER_NOT_FOUND));

member.updateRefreshToken(null);
memberRepository.save(member);
RefreshToken refreshToken = refreshTokenRepository.findByMember(member)
.orElseThrow(() -> new MemberHandler(ErrorStatus.REFRESHTOKEN_NULL));

refreshTokenRepository.delete(refreshToken);
}


Expand Down
Loading