Skip to content

Commit

Permalink
[JT-29] feat: ThreadLocal, Interceptor 추가 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
Shin-Jae-Yoon committed Sep 6, 2023
2 parents cbb4682 + 14524f1 commit aab3b95
Show file tree
Hide file tree
Showing 9 changed files with 88 additions and 16 deletions.
1 change: 1 addition & 0 deletions module-application/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ dependencies {
// JWT
implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,16 @@
@RequestMapping("/members")
public class MemberController {

private final MemberService memberService;
private final MemberService memberService;

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void signUp(@RequestBody @Valid SignUpReq signUpReq) {
memberService.createMember(signUpReq);
}
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void signUp(@RequestBody @Valid SignUpReq signUpReq) {
memberService.createMember(signUpReq);
}

@GetMapping("/email-authorization")
public String authenticateEmail(@RequestParam(value = "email") String email) {
return memberService.sendEmailAuthentication(email);
}
@GetMapping("/email-authorization")
public String authenticateEmail(@RequestParam(value = "email") String email) {
return memberService.sendEmailAuthentication(email);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.devtoon.jtoon.security.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import com.devtoon.jtoon.security.interceptor.MemberInterceptor;

@Configuration
public class WebConfig implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MemberInterceptor())
.addPathPatterns("/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
import org.springframework.web.servlet.HandlerExceptionResolver;

import com.devtoon.jtoon.security.jwt.JwtProvider;
import com.devtoon.jtoon.security.jwt.domain.CustomUserDetails;
import com.devtoon.jtoon.security.jwt.domain.MemberThreadLocal;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -36,7 +38,10 @@ protected void doFilterInternal(
String token = header.split(" ")[1];
jwtProvider.validateToken(token);
Authentication auth = jwtProvider.getAuthentication(token);
CustomUserDetails customUserDetails = (CustomUserDetails)auth.getPrincipal();

SecurityContextHolder.getContext().setAuthentication(auth);
MemberThreadLocal.setMember(customUserDetails.getMember());
} catch (RuntimeException e) {
log.error("Invalid Token", e);
handlerExceptionResolver.resolveException(request, response, null, e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.devtoon.jtoon.security.interceptor;

import org.jetbrains.annotations.NotNull;
import org.springframework.web.servlet.HandlerInterceptor;

import com.devtoon.jtoon.security.jwt.domain.MemberThreadLocal;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

public class MemberInterceptor implements HandlerInterceptor {

@Override
public void afterCompletion(
@NotNull HttpServletRequest request,
@NotNull HttpServletResponse response,
@NotNull Object handler,
Exception ex) throws Exception {
if (MemberThreadLocal.getMember() != null) {
MemberThreadLocal.clear();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import com.devtoon.jtoon.security.jwt.application.CustomUserDetailsService;
import com.devtoon.jtoon.security.jwt.domain.CustomUserDetails;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
Expand Down Expand Up @@ -36,7 +36,7 @@ public class JwtProvider {

private Key secretKey;

private final UserDetailsService userDetailsService;
private final CustomUserDetailsService userDetailsService;

@PostConstruct
private void init() {
Expand Down Expand Up @@ -71,7 +71,7 @@ public void validateToken(String token) {

public Authentication getAuthentication(String token) {
String ClaimsEmail = parseClaimsBody(token).getSubject();
UserDetails userDetails = userDetailsService.loadUserByUsername(ClaimsEmail);
CustomUserDetails userDetails = userDetailsService.loadUserByUsername(ClaimsEmail);

return new UsernamePasswordAuthenticationToken(userDetails, " ", userDetails.getAuthorities());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.devtoon.jtoon.security.jwt.application;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
Expand All @@ -17,7 +16,7 @@ public class CustomUserDetailsService implements UserDetailsService {
private final MemberRepository memberRepository;

@Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
public CustomUserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
Member member = memberRepository.findByEmail(email)
.orElseThrow(() -> new UsernameNotFoundException("Invalid Email"));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,8 @@ public boolean isCredentialsNonExpired() {
public boolean isEnabled() {
return true;
}

public Member getMember() {
return member;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.devtoon.jtoon.security.jwt.domain;

import com.devtoon.jtoon.member.entity.Member;

public final class MemberThreadLocal {

private static final ThreadLocal<Member> memberThreadLocal;

static {
memberThreadLocal = new ThreadLocal<>();
}

public static Member getMember() {
return memberThreadLocal.get();
}

public static void setMember(Member member) {
memberThreadLocal.set(member);
}

public static void clear() {
memberThreadLocal.remove();
}
}

0 comments on commit aab3b95

Please sign in to comment.