개인 프로젝트/블로그

springSecruty+JWT+react+Oauth2 (react)

공주맛밤 2022. 7. 18. 16:51

<Login>: 임시 로그인 페이지

import { Badge } from "react-bootstrap";
import React from "react";
import { useNavigate } from "react-router-dom";

const Login = () => {
  const navigate = useNavigate();

  const handleLogin = () => {
    window.location.href = `http://localhost:8080/oauth2/authorization/google`;
  };

  const handleLogout = () => {
    //accessToken과 refreshToken을 지움
    localStorage.removeItem("Tnut's accessToken");
    localStorage.removeItem("Tnut's refreshToken");
    navigate("/");
  };

  return (
    <div>
      <br />
      <br />
      <br />
      <Badge bg="secondary" onClick={handleLogin}>
        구글 로그인
      </Badge>
      <br />
      <Badge bg="secondary" onClick={handleLogout}>
        로그 아웃
      </Badge>
    </div>
  );
};

export default Login;

<Redirect> : jwt토큰 쿼리스트링으로 받는 곳

import React, { useEffect } from "react";
import queryString from "query-string";
import { useNavigate } from "react-router-dom";

const Redirect = () => {
  const navigate = useNavigate();

  const token = queryString.parse(window.location.search); //yarn add query-string

  useEffect(() => {
    if (token) {
      localStorage.setItem("Tnut's accessToken", token.accessToken);
      localStorage.setItem("Tnut's refreshToken", token.refreshToken);
      setInterval(() => {
        //로그인 시 29분 간격으로 accessToken 재발급
        fetch("http://localhost:8080/refresh", {
          //access토큰이 만료되었을 경우(다양한 경우가 있지만 일단은)
          method: "post",
          headers: {
            "Content-Type": "applicaiton/json; charset=utf-8",
            RefreshToken: localStorage.getItem("Tnut's refreshToken"),
          },
        })
          .then((res) => res.json())
          .then((res) => {
            if (res.status === 200) {
              localStorage.setItem("Tnut's accessToken", res.data); //access토큰을 새로 발급
            } else if (res.status === 401) {
              clearInterval(setInterval); //refreshToken 만료 시 재발급 중지
              alert("로그인 만료, 재 로그인 해주세요");
            }
          });
      }, 1000 * 60 * 29);
      navigate("/login");
    } else {
      navigate("/");
    }
  });

  return <div></div>;
};

export default Redirect;

<권한이 필요한 요청시>

fetch("http://localhost:8080/api/board/save", {
      method: "post",
      headers: {
        "Content-Type": "application/json; charset=utf-8",
        AccessToken: localStorage.getItem("Tnut's accessToken"),
      },
      body: JSON.stringify(board),
    })

과 같이 header에 accessToken을 담아줌

728x90
반응형