Skip to content

Commit

Permalink
Merge pull request #127 from TaetaetaE01/main
Browse files Browse the repository at this point in the history
[refactor] : 패키징 구조 변경, 패키지 import
  • Loading branch information
TaetaetaE01 authored Oct 3, 2024
2 parents 2876ca7 + 73d6e67 commit a21db88
Show file tree
Hide file tree
Showing 102 changed files with 419 additions and 425 deletions.
13 changes: 13 additions & 0 deletions docker-compose-local.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: "3.8"

services:
big-brother-local:
image: mysql:8.0
restart: always
environment:
MYSQL_ROOT_PASSWORD: 1234
MYSQL_DATABASE: bigbrother
volumes:
- ./db/mysql/data:/var/lib/mysql
ports:
- "3307:3306"
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package com.example.bigbrotherbe.global.security;
package com.example.bigbrotherbe.auth.custom;

import com.example.bigbrotherbe.domain.member.entity.CustomerDetails;
import com.example.bigbrotherbe.domain.member.entity.Member;
import com.example.bigbrotherbe.domain.member.repository.MemberRepository;
import com.example.bigbrotherbe.global.exception.BusinessException;
import com.example.bigbrotherbe.global.exception.enums.ErrorCode;
import com.example.bigbrotherbe.common.exception.BusinessException;
import com.example.bigbrotherbe.common.exception.enums.ErrorCode;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
Expand All @@ -18,9 +17,8 @@ public class CustomUserDetailsService implements UserDetailsService {

@Override
public UserDetails loadUserByUsername(String userEmail) throws UsernameNotFoundException {
Member member = memberRepository.findByEmail(userEmail).orElseThrow(() -> new BusinessException(
ErrorCode.NO_EXIST_EMAIL));
Member member = memberRepository.findByEmail(userEmail).orElseThrow(()
-> new BusinessException(ErrorCode.NO_EXIST_EMAIL));
return new CustomerDetails(member);
}

}
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package com.example.bigbrotherbe.domain.member.entity;
package com.example.bigbrotherbe.auth.custom;

import java.util.Collection;
import java.util.stream.Collectors;
import lombok.AllArgsConstructor;

import com.example.bigbrotherbe.domain.member.entity.Member;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.GrantedAuthority;
Expand All @@ -14,11 +15,12 @@
public class CustomerDetails implements UserDetails {

private final Member member;

@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return member.getAffiliations().stream()
.map(affiliationMember -> new SimpleGrantedAuthority(affiliationMember.getRole()))
.collect(Collectors.toList());
.map(affiliationMember -> new SimpleGrantedAuthority(affiliationMember.getRole()))
.collect(Collectors.toList());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.bigbrotherbe.global.jwt.entity;
package com.example.bigbrotherbe.auth.jwt.dto;

import lombok.Builder;
import lombok.Getter;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.bigbrotherbe.global.jwt.entity;
package com.example.bigbrotherbe.auth.jwt.dto.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.example.bigbrotherbe.global.jwt.entity;
package com.example.bigbrotherbe.auth.jwt.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package com.example.bigbrotherbe.global.jwt;
import com.example.bigbrotherbe.global.exception.BusinessException;
import com.example.bigbrotherbe.global.exception.response.ApiResponse;
import com.example.bigbrotherbe.global.jwt.component.JwtTokenProvider;
package com.example.bigbrotherbe.auth.jwt.filter;

import com.example.bigbrotherbe.common.exception.BusinessException;
import com.example.bigbrotherbe.common.exception.response.ApiResponse;
import com.example.bigbrotherbe.auth.jwt.service.JwtTokenService;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.IOException;

import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -20,30 +23,28 @@
@Slf4j
public class JwtAuthenticationFilter extends OncePerRequestFilter {

private final JwtTokenProvider jwtTokenProvider;
private final JwtTokenService jwtTokenService;

@Override
protected void doFilterInternal(@NonNull HttpServletRequest servletRequest,
@NonNull HttpServletResponse servletResponse,
FilterChain filterChain) throws ServletException, IOException {
@NonNull HttpServletResponse servletResponse,
FilterChain filterChain) throws ServletException, IOException {
try {
String token = resolveToken(servletRequest);
if (token != null && jwtTokenProvider.validateToken(token)
&& jwtTokenProvider.checkTokenType(token)) {
if (token != null && jwtTokenService.validateToken(token)
&& jwtTokenService.checkTokenType(token)) {
// 유효한 엑세스 토큰이 있는 경우
Authentication authentication = jwtTokenProvider.getAuthentication(token);
Authentication authentication = jwtTokenService.getAuthentication(token);
SecurityContextHolder.getContext().setAuthentication(authentication);
}
filterChain.doFilter(servletRequest, servletResponse);
}
catch (BusinessException e) {
} catch (BusinessException e) {
handleException((HttpServletResponse) servletResponse, e);
// 예외 처리 로직
}

}
private void handleException(HttpServletResponse response, BusinessException e) throws IOException {

private void handleException(HttpServletResponse response, BusinessException e) throws IOException {
if (e != null) {
response.setContentType("application/json");
response.setStatus(400);
Expand All @@ -54,6 +55,7 @@ private void handleException(HttpServletResponse response, BusinessException e)
response.getWriter().write("{\"error\": \"An unexpected error occurred.\"}");
}
}

private String resolveToken(HttpServletRequest request) {
String bearerToken = request.getHeader("Authorization");
if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.example.bigbrotherbe.global.jwt.component;

import static com.example.bigbrotherbe.global.exception.enums.ErrorCode.ACCESS_TOKEN_EXPIRED;
import static com.example.bigbrotherbe.global.exception.enums.ErrorCode.REFRESH_TOKEN_EXPIRED;
import static com.example.bigbrotherbe.global.jwt.entity.TokenDto.ACCESS_TOKEN;
import static com.example.bigbrotherbe.global.jwt.entity.TokenDto.REFRESH_TOKEN;

import com.example.bigbrotherbe.global.exception.BusinessException;
import com.example.bigbrotherbe.global.exception.enums.ErrorCode;
import com.example.bigbrotherbe.global.jwt.entity.JwtToken;
import com.example.bigbrotherbe.global.jwt.entity.TokenDto;
import com.example.bigbrotherbe.global.security.CustomUserDetailsService;
package com.example.bigbrotherbe.auth.jwt.service;

import static com.example.bigbrotherbe.common.exception.enums.ErrorCode.ACCESS_TOKEN_EXPIRED;
import static com.example.bigbrotherbe.common.exception.enums.ErrorCode.REFRESH_TOKEN_EXPIRED;
import static com.example.bigbrotherbe.auth.jwt.dto.TokenDto.ACCESS_TOKEN;
import static com.example.bigbrotherbe.auth.jwt.dto.TokenDto.REFRESH_TOKEN;

import com.example.bigbrotherbe.common.exception.BusinessException;
import com.example.bigbrotherbe.common.exception.enums.ErrorCode;
import com.example.bigbrotherbe.auth.jwt.dto.response.JwtToken;
import com.example.bigbrotherbe.auth.jwt.dto.TokenDto;
import com.example.bigbrotherbe.auth.custom.CustomUserDetailsService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
Expand All @@ -28,22 +28,22 @@
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

@Slf4j
@Component
public class JwtTokenProvider {
public class JwtTokenService {

private final Key key;
private static final long ACCESS_TIME = 10 * 60 * 1000L; // 10분
private static final long REFRESH_TIME = 30 * 60 * 1000L; //30분

private final CustomUserDetailsService customerDetailsService;

public JwtTokenProvider(@Value("${jwt.secret}") String secretKey,CustomUserDetailsService customerDetailsService) {
public JwtTokenService(@Value("${jwt.secret}") String secretKey, CustomUserDetailsService customerDetailsService) {
byte[] keyBytes = Decoders.BASE64.decode(secretKey);
this.key = Keys.hmacShaKeyFor(keyBytes);
this.customerDetailsService = customerDetailsService;
Expand All @@ -52,8 +52,9 @@ public JwtTokenProvider(@Value("${jwt.secret}") String secretKey,CustomUserDetai
// Member 정보를 가지고 Access Token, RefreshToken을 생성하는 메서드
public JwtToken generateToken(Authentication authentication) {
// 권한 가져오기
String authorities = authentication.getAuthorities().stream().map(GrantedAuthority::getAuthority).collect(
Collectors.joining(","));
String authorities = authentication.getAuthorities().stream()
.map(GrantedAuthority::getAuthority)
.collect(Collectors.joining(","));

TokenDto tokenDto = createAllToken(authentication.getName(), authorities);

Expand All @@ -64,33 +65,21 @@ public JwtToken generateToken(Authentication authentication) {
.build();
}

private String createToken(String email, String authorities, String type) {
long now = new Date().getTime();
long expiration = type.equals("Access") ? ACCESS_TIME : REFRESH_TIME;
return Jwts.builder()
.setSubject(email)
.claim("auth", authorities)
.claim("type", type)
.setExpiration(new Date(now + expiration))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}

public Authentication getAuthentication(String token) {
Claims claims = parseClaims(token);
log.info("Parsed claims: {}", claims);
if (claims.get("auth") == null) {
throw new RuntimeException("권한 정보가 없는 토큰입니다.");
}
UserDetails principal = customerDetailsService.loadUserByUsername(
claims.getSubject());
claims.getSubject());
return new UsernamePasswordAuthenticationToken(principal, "", principal.getAuthorities());
}

public boolean validateToken(String token) {

try {
Jwts.parserBuilder()
Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
Expand Down Expand Up @@ -124,18 +113,6 @@ public boolean checkTokenType(String token) {
}


private Claims parseClaims(String accessToken) {
try {
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody();
} catch (ExpiredJwtException e) {
return e.getClaims();
}
}

public String createTokenByRefreshToken(String refreshToken) {
Claims claims = getAllClaimsFromToken(refreshToken);
Date now = new Date();
Expand All @@ -153,13 +130,6 @@ public TokenDto createAllToken(String email, String role) {
return new TokenDto(createToken(email, role, ACCESS_TOKEN), createToken(email, role, REFRESH_TOKEN));
}

private Claims getAllClaimsFromToken(String token) {
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
}

public TokenDto refreshAccessToken(String refreshToken) {

Expand All @@ -185,4 +155,36 @@ private String resolveToken(String token) {
throw new BusinessException(ErrorCode.ILLEGAL_HEADER_PATTERN);
}

private String createToken(String email, String authorities, String type) {
long now = new Date().getTime();
long expiration = type.equals("Access") ? ACCESS_TIME : REFRESH_TIME;

return Jwts.builder()
.setSubject(email)
.claim("auth", authorities)
.claim("type", type)
.setExpiration(new Date(now + expiration))
.signWith(key, SignatureAlgorithm.HS256)
.compact();
}

private Claims getAllClaimsFromToken(String token) {
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(token)
.getBody();
}

private Claims parseClaims(String accessToken) {
try {
return Jwts.parserBuilder()
.setSigningKey(key)
.build()
.parseClaimsJws(accessToken)
.getBody();
} catch (ExpiredJwtException e) {
return e.getClaims();
}
}
}
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
package com.example.bigbrotherbe.global.jwt.component;
package com.example.bigbrotherbe.auth.util;

import com.example.bigbrotherbe.domain.member.entity.Member;
import com.example.bigbrotherbe.domain.member.entity.role.AffiliationMember;
import com.example.bigbrotherbe.domain.member.entity.AffiliationMember;
import com.example.bigbrotherbe.domain.member.repository.AffiliationMemberRepository;
import com.example.bigbrotherbe.domain.member.repository.AffiliationRepository;
import com.example.bigbrotherbe.domain.member.repository.MemberRepository;
import com.example.bigbrotherbe.global.jwt.entity.JwtToken;
import com.example.bigbrotherbe.auth.jwt.dto.response.JwtToken;

import java.util.List;

import com.example.bigbrotherbe.global.exception.BusinessException;
import com.example.bigbrotherbe.common.exception.BusinessException;
import com.example.bigbrotherbe.auth.jwt.service.JwtTokenService;
import lombok.RequiredArgsConstructor;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;

import static com.example.bigbrotherbe.common.exception.enums.ErrorCode.*;
import static com.example.bigbrotherbe.domain.member.entity.enums.AffiliationCode.STUDENT_COUNCIL;
import static com.example.bigbrotherbe.domain.member.entity.enums.Role.*;
import static com.example.bigbrotherbe.global.exception.enums.ErrorCode.*;
import static com.example.bigbrotherbe.domain.member.entity.role.Role.*;

@Component
@RequiredArgsConstructor
Expand All @@ -29,7 +30,7 @@ public class AuthUtil {
private final AffiliationMemberRepository affiliationMemberRepository;
private final AffiliationRepository affiliationRepository;
private final AuthenticationManagerBuilder authenticationManagerBuilder;
private final JwtTokenProvider jwtTokenProvider;
private final JwtTokenService jwtTokenService;

public Member getLoginMember() {
try {
Expand Down Expand Up @@ -87,12 +88,13 @@ public Long getAffiliationIdByMemberId(Long memberId, String affiliation) {
.orElseThrow(() -> new BusinessException(NO_FOUND_AFFILIATION));
}


public JwtToken createAuthenticationToken(String email, String password) {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);
try {
UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(email, password);
Authentication authentication = authenticationManagerBuilder.getObject()
.authenticate(authenticationToken);
return jwtTokenProvider.generateToken(authentication);
.authenticate(authenticationToken);
return jwtTokenService.generateToken(authentication);
} catch (Exception e) {
throw new BusinessException(MISMATCH_PASSWORD);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.example.bigbrotherbe.global.filter;
package com.example.bigbrotherbe.common.config;


import static com.example.bigbrotherbe.global.constant.Constant.Url.DOMAIN_URL;
import static com.example.bigbrotherbe.common.constant.Constant.Url.DOMAIN_URL;

import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
Expand Down
Loading

0 comments on commit a21db88

Please sign in to comment.