본문 바로가기
개발/Security

[SpringBoot] Security + JWT(Access , Refresh) - Controller

by 코딩하는 흰둥이 2024. 9. 25.

이전글

https://greed-yb.tistory.com/291

 

[SpringBoot] Security + JWT(Access , Refresh) - Handler

이전글https://greed-yb.tistory.com/290 [SpringBoot] Security + JWT(Access , Refresh) - JwtAuthenticationFilter이전글https://greed-yb.tistory.com/289 [SpringBoot] Security + JWT(Access , Refresh) - JwtTokenUtil이전글https://greed-yb.tistory.com/2

greed-yb.tistory.com

 

 

controller.class
import com.example.practice.security.jwt.JwtTokenUtil;
import com.example.practice.service.user.UserService;
import com.example.practice.vo.UserVo;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

@Controller
public class WebController {

    @Autowired
    private UserService userService;

    private final JwtTokenUtil jwtTokenUtil;

    public WebController(JwtTokenUtil jwtTokenUtil) {
        this.jwtTokenUtil = jwtTokenUtil;
    }

    @GetMapping("/login")
    public String loginPage(HttpServletRequest request, HttpServletResponse response) throws Exception{
        System.err.println("Login Page~~~~");
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        // 로그인 정보가 없으면 loginPage 로 있으면 / 메인페이지로
        if (authentication instanceof AnonymousAuthenticationToken) {
            return "login";
        }
        return "redirect:/";
    }



    @PostMapping("/login")
    public String login(@RequestParam("id") String username, @RequestParam("password") String password, HttpServletResponse response, Model model) throws Exception {
        try {
            // 사용자 인증
            Authentication authentication = new UsernamePasswordAuthenticationToken(username, password);
            // 사용자 정보 set
            SecurityContextHolder.getContext().setAuthentication(authentication);

            //private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); 참고
            PasswordEncoder passwordEncoder = userService.passwordEncoder();
            // 사용자 정보가 유효한지 확인
            UserVo userVo = userService.getUserById(username);
            // 사용자가 입력한 비밀번호와 DB의 비밀번호가 일치하지 않으면 login 페이지로 이동
            if (userVo == null || !passwordEncoder.matches(password, userVo.getPassword())) {
                // 인증 실패 시 다시 로그인 페이지로
                return "login";
            }

            // JWT 토큰 생성
            String accessToken = jwtTokenUtil.generateAccessToken(username);
            String refreshToken = jwtTokenUtil.generateRefreshToken(username);

            // 쿠키에 JWT 저장
            Cookie accessTokenCookie = new Cookie("accessToken", accessToken);
            accessTokenCookie.setHttpOnly(true);
            accessTokenCookie.setPath("/");
            accessTokenCookie.setMaxAge(60 * 60); // 1시간
//            accessTokenCookie.setMaxAge(1 * 60); // 1분
            response.addCookie(accessTokenCookie);

            Cookie refreshTokenCookie = new Cookie("refreshToken", refreshToken);
            refreshTokenCookie.setHttpOnly(true);
            refreshTokenCookie.setPath("/");
            refreshTokenCookie.setMaxAge(7 * 24 * 60 * 60); // 7일
//            refreshTokenCookie.setMaxAge(5 * 60); // 5분
            response.addCookie(refreshTokenCookie);

            // 로그인 성공 시 메인 페이지로 이동
            return "redirect:/";

        } catch (Exception e) {
            return "login";
        }
    }


    // 로그아웃 처리
    @PostMapping("/logout")
    public String logout(HttpServletResponse response) {
        // 쿠키에서 accessToken 제거
        Cookie accessTokenCookie = new Cookie("accessToken", null);
        accessTokenCookie.setMaxAge(0); // 쿠키 만료
        response.addCookie(accessTokenCookie);

        // 쿠키에서 refreshToken 제거
        Cookie refreshTokenCookie = new Cookie("refreshToken", null);
        refreshTokenCookie.setMaxAge(0); // 쿠키 만료
        response.addCookie(refreshTokenCookie);

        // 로그아웃 후 로그인 페이지로
        return "login";
    }


    // 권한 인증 실패
    @GetMapping("/denied")
    public String denied(Model model){
        String exception = "권한이 없습니다";
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String id = (String)authentication.getPrincipal();
        model.addAttribute("id",id);
        model.addAttribute("exception",exception);
        return "denied";
    }
    
}

 

프로젝트 및 사람마다 방식이 다 다르니 이런 흐름으로 간다 정도만 이해하면 된다

댓글