Skip to content

Commit

Permalink
Merge branch 'main' into feat/#31
Browse files Browse the repository at this point in the history
  • Loading branch information
KimKyoHwee authored Apr 9, 2024
2 parents 6eb7fc8 + 0cc1789 commit 5bc5f41
Show file tree
Hide file tree
Showing 42 changed files with 939 additions and 732 deletions.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/♻️--refactor-.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: "♻️ [REFACTOR]"
about: 리팩토링 이슈 템플릿입니다.
title: "♻️ [REFACTOR]"
labels: "♻️ refactor"
assignees: ''

---

# Title
- tmp

# Content
- tmp

# TODO
- [ ] tmp
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/✨--feat--.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: "✨ [FEAT] "
about: 기능 개발 이슈 템플릿입니다.
title: "✨ [FEAT] "
labels: "✨ feature"
assignees: ''

---

# Title
- tmp

# Content
- tmp

# TODO
- [ ] tmp
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/🐛--bug-.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: "\U0001F41B [BUG]"
about: 버그 이슈 템플릿입니다.
title: "\U0001F41B [BUG]"
labels: "\U0001F41B bug"
assignees: ''

---

# Title
- tmp

# Content
- tmp

# TODO
- [ ] tmp
8 changes: 8 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# 🔎 Resolved Issue
- tmp

# ✅ Title
- tmp

# 📄 Content
- tmp
19 changes: 10 additions & 9 deletions src/main/java/com/soongsil/CoffeeChat/config/SecurityConfig.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
package com.soongsil.CoffeeChat.config;

import com.soongsil.CoffeeChat.config.jwt.CustomLogoutFilter;
import com.soongsil.CoffeeChat.config.jwt.JWTFilter;
import com.soongsil.CoffeeChat.config.jwt.JWTUtil;
import com.soongsil.CoffeeChat.config.oauth2.CustomSuccessHandler;
import com.soongsil.CoffeeChat.repository.RefreshRepository;
import com.soongsil.CoffeeChat.service.CustomOAuth2UserService;
import jakarta.servlet.http.HttpServletRequest;
import java.util.Collections;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
Expand All @@ -20,7 +14,14 @@
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;

import java.util.Collections;
import com.soongsil.CoffeeChat.config.jwt.CustomLogoutFilter;
import com.soongsil.CoffeeChat.config.jwt.JWTFilter;
import com.soongsil.CoffeeChat.config.jwt.JWTUtil;
import com.soongsil.CoffeeChat.config.oauth2.CustomSuccessHandler;
import com.soongsil.CoffeeChat.repository.RefreshRepository;
import com.soongsil.CoffeeChat.service.CustomOAuth2UserService;

import jakarta.servlet.http.HttpServletRequest;

@Configuration
@EnableWebSecurity
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package com.soongsil.CoffeeChat.config.jwt;

import java.io.IOException;

import org.springframework.web.filter.GenericFilterBean;

import com.soongsil.CoffeeChat.repository.RefreshRepository;

import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
Expand All @@ -9,95 +14,98 @@
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.filter.GenericFilterBean;

import java.io.IOException;

public class CustomLogoutFilter extends GenericFilterBean {
private final JWTUtil jwtUtil;
private final RefreshRepository refreshRepository;

public CustomLogoutFilter(JWTUtil jwtUtil, RefreshRepository refreshRepository) {

this.jwtUtil = jwtUtil;
this.refreshRepository = refreshRepository;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
}
private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {

//path and method verify
String requestUri = request.getRequestURI(); //요청의 path값을 꺼내고
if (!requestUri.matches("^\\/logout$")) { //logout경로인지 확인 후

filterChain.doFilter(request, response);
return;
}
String requestMethod = request.getMethod();
if (!requestMethod.equals("POST")) { //POST요청인지 확인

filterChain.doFilter(request, response);
return;
}

//get refresh token
String refresh = null;
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {

if (cookie.getName().equals("refresh")) {

refresh = cookie.getValue();
}
}

//refresh null check 400 (refresh토큰이 null상태)
if (refresh == null) {

response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//expired check
try {
jwtUtil.isExpired(refresh);
} catch (ExpiredJwtException e) {

//response status code 400 (만료된 토큰)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

// 토큰이 refresh인지 확인 (발급시 페이로드에 명시)
String category = jwtUtil.getCategory(refresh);
if (!category.equals("refresh")) {

//response status code 400 (refresh토큰이 아님)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//DB에 저장되어 있는지 확인
Boolean isExist = refreshRepository.existsByRefresh(refresh);
if (!isExist) {

//response status code 400 (DB에 저장된 refresh 토큰이 아님)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//로그아웃 진행
//Refresh 토큰 DB에서 제거 (앞으로 해당 refresh토큰으로 reissue불가능)
refreshRepository.deleteByRefresh(refresh);

//Refresh 토큰 Cookie 값 0 (null인 refresh토큰 반환)
Cookie cookie = new Cookie("refresh", null);
cookie.setMaxAge(0);
cookie.setPath("/");

response.addCookie(cookie);
response.setStatus(HttpServletResponse.SC_OK);
}
private final JWTUtil jwtUtil;
private final RefreshRepository refreshRepository;

public CustomLogoutFilter(JWTUtil jwtUtil, RefreshRepository refreshRepository) {

this.jwtUtil = jwtUtil;
this.refreshRepository = refreshRepository;
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws
IOException,
ServletException {
doFilter((HttpServletRequest)request, (HttpServletResponse)response, chain);
}

private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws
IOException,
ServletException {

//path and method verify
String requestUri = request.getRequestURI(); //요청의 path값을 꺼내고
if (!requestUri.matches("^\\/logout$")) { //logout경로인지 확인 후

filterChain.doFilter(request, response);
return;
}
String requestMethod = request.getMethod();
if (!requestMethod.equals("POST")) { //POST요청인지 확인

filterChain.doFilter(request, response);
return;
}

//get refresh token
String refresh = null;
Cookie[] cookies = request.getCookies();
for (Cookie cookie : cookies) {

if (cookie.getName().equals("refresh")) {

refresh = cookie.getValue();
}
}

//refresh null check 400 (refresh토큰이 null상태)
if (refresh == null) {

response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//expired check
try {
jwtUtil.isExpired(refresh);
} catch (ExpiredJwtException e) {

//response status code 400 (만료된 토큰)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

// 토큰이 refresh인지 확인 (발급시 페이로드에 명시)
String category = jwtUtil.getCategory(refresh);
if (!category.equals("refresh")) {

//response status code 400 (refresh토큰이 아님)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//DB에 저장되어 있는지 확인
Boolean isExist = refreshRepository.existsByRefresh(refresh);
if (!isExist) {

//response status code 400 (DB에 저장된 refresh 토큰이 아님)
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return;
}

//로그아웃 진행
//Refresh 토큰 DB에서 제거 (앞으로 해당 refresh토큰으로 reissue불가능)
refreshRepository.deleteByRefresh(refresh);

//Refresh 토큰 Cookie 값 0 (null인 refresh토큰 반환)
Cookie cookie = new Cookie("refresh", null);
cookie.setMaxAge(0);
cookie.setPath("/");

response.addCookie(cookie);
response.setStatus(HttpServletResponse.SC_OK);
}
}
23 changes: 19 additions & 4 deletions src/main/java/com/soongsil/CoffeeChat/config/jwt/JWTFilter.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
package com.soongsil.CoffeeChat.config.jwt;


import java.io.IOException;
import java.io.PrintWriter;

import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import com.soongsil.CoffeeChat.dto.CustomOAuth2User;
import com.soongsil.CoffeeChat.dto.UserDTO;
import com.soongsil.CoffeeChat.entity.User;


import io.jsonwebtoken.ExpiredJwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

Expand All @@ -16,8 +24,6 @@
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;
import java.io.PrintWriter;

public class JWTFilter extends OncePerRequestFilter { //요청당 한번만 실행되면 됨
private final JWTUtil jwtUtil; //JWT검증 위하여 주입
Expand All @@ -26,6 +32,15 @@ public JWTFilter(JWTUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}


public class JWTFilter extends OncePerRequestFilter { //요청당 한번만 실행되면 됨
private final JWTUtil jwtUtil; //JWT검증 위하여 주입

public JWTFilter(JWTUtil jwtUtil) {
this.jwtUtil = jwtUtil;
}


@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
Expand Down
Loading

0 comments on commit 5bc5f41

Please sign in to comment.