๋ณธ๋ด์ฉ์ ํ์์ " React&Python์ผ๋ก ์น๊ฐ๋ฐ(๋งํฌ์๋น์ค)" ์นดํ ๊ณ ๋ฆฌ ๊ฐ๋ฐ์์ค์ ์ถ๊ฐํ๋ ๋ฐฉ์์ผ๋ก ์งํํฉ๋๋ค.
( ์์ค ํด๋๋ ์ ์นดํ ๊ณ ๋ฆฌ๋ฅผ ์ ์ฝ์ด๋ณด๊ณ , git ์์ค๋ฅผ ์ฐธ๊ณ ํ์๊ธฐ ๋ฐ๋๋๋ค. )
์ง๋ํธ์์๋ http://localhost:3000 ์ ๊ทผ์ ๋ฐ๋ก ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ๋์ค๋๋ก ์ฒ๋ฆฌํ๊ณ ,
์ด๋ฒํธ์๋ admin ๋ฒํผ ํด๋ฆญ ํน์ ๋ก๊ทธ์ธ ์์ด์ฝ์ ํด๋ฆญ ํ ๋ Keycloak ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ๋์ค๋๋ก ์์ ํด๋ณด์.
์ด์ ์ material-icons๋ฅผ ํตํ menu.jsx๋ฅผ ์ ์ํ๋ค. ์๋ ์ด์ ๊ธ ์ฐธ๊ณ ๋ฐ๋๋๋ค.
#14. material-icons ๋ฅผ ํตํ ๋ฉ๋ดํ๋ฉด
๊ธฐ์กด menu.jsx ์ SettingsIcon ํด๋ฆญ์ Keycloak์ ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋ํ๋๋ก ์์ ํ๋ค.
์ด 3๊ฐ์ ์์ค๋ฅผ ์์ ํ ์์ ์ด๋ค.
1. menu.jsx
2. App.js
3. index.js
โ menu.jsx ( ์์น: linkservice/client/src/component/menu.jsx )
---------------------------------------------------------------------------------------------------
์ฐ์ react-keycloak/web ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊ตฌ์ฑ์์๊ฐ Keycloak์ Accessํด์ผํ๋ ๊ฒฝ์ฐ
useKeycloak Hook๋ฅผ ์ฌ์ฉํด์ผํ๋ค.
import { useKeycloak } from "@react-keycloak/web";
useKeycloak๊ตฌ์กฐํ๋ ๊ฐ์ฒด๋ฅผ Destructuring ํ์ฌ ๊ฐ๋ณ์ ์ธ ๋ณ์์ ํ ๋นํ๋ค.
const { keycloak } = useKeycloak();
์ด๋ ๊ฒ ํจ์ผ๋ก์จ, ๋ชจ๋ keycloak ๋ฉ์๋ ๋ฐ ๋ณ์์ ์ก์ธ์คํ ์ ์์ต๋๋ค.
handleIcon ์ด๋ฒคํธ์ keycloak.authenticated (์ธ์ฆ์ด๋์๋์ง) ์ ๋ฐ๋ผ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ํธ์ถํด๋ณด์.
// keycloak์ ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด, keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ
if (!keycloak.authenticated) {
alert("๋ก๊ทธ์ธ์ด ํ์ํ ์๋น์ค์
๋๋ค.")
// keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ
keycloak.login();
}
์์ ๊ฐ์ด handle ์ด๋ฒคํธ์ ๋ฐ๋ผ ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ํธ์ถํ ์์์ผ๋ฉฐ,
์ด๋ฏธ ๋ก๊ทธ์ธ์ด ๋์๋ค๋ฉด ๊ด๋ฆฌ์ ํ๋ฉด์ผ๋ก ๋ฐ๋ก ์ด๋์ด ๊ฐ๋ฅํ๋ค.
์ ๋ด์ฉ์์ ์ถ๊ฐ์ ์ผ๋ก keycloak.login() ํ ๊ธฐ๋ณธ redirect-uri ์ด http://localhost:3000 ์ด๋ค.
์ฆ, ๊ด๋ฆฌ์ ํ๋ฉด์ผ๋ก ์ด๋์ ๋ก๊ทธ์ธ ํ ๋ฐ๋ก ์ด๋์ด ์๋๊ณ , ์ดํ๋ฉด์ด ๋์จ๋ค๋ ๋ป์ด๋ค.
๊ทธ๋์ redirect-uri๋ฅผ ๊ด๋ฆฌ์ ํ๋ฉด์ผ๋ก ์ง์ ์ด ๊ฐ๋ฅํ๋ค.
// keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ์ redirectUri๋ฅผ ๊ฐ์ธํ๊ฐ ๊ฐ๋ฅํ๋ค.
keycloak.redirectUri= window.location.href + '/manager'
์์ ๋ menu.jsx
import HomeIcon from '@mui/icons-material/Home';
import SettingsIcon from '@mui/icons-material/Settings';
import { useNavigate } from 'react-router-dom';
// useKeycloak import
import { useKeycloak } from "@react-keycloak/web";
export default function MenuIcon(props) {
const navigator = useNavigate()
// Using Object destructuring
const { keycloak } = useKeycloak();
const handleIcon = (e) => {
switch (e) {
case 'A' :
// keycloak์ ๋ก๊ทธ์ธ์ด ๋์ด ์์ง ์๋ค๋ฉด, keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ
if (!keycloak.authenticated) {
alert("๋ก๊ทธ์ธ์ด ํ์ํ ์๋น์ค์
๋๋ค.")
// keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ์ redirectUri๋ฅผ ๊ฐ์ธํ๊ฐ ๊ฐ๋ฅํ๋ค.
keycloak.redirectUri= window.location.href + '/manager'
// keycloak ๋ก๊ทธ์ธ ํ์ด์ง ํธ์ถ
keycloak.login();
}
return navigator('/manager')
case 'M' : return navigator('/')
default : return navigator('/')
}
}
return (
<>
<div className='menu-wrap'>
<div className='menu-box'>
<HomeIcon fontSize='large' color="secondary"
onClick={() => handleIcon('M')}
/>
<SettingsIcon fontSize='large' color="secondary"
onClick={() => handleIcon('A')}
/>
</div>
</div>
</>
)
}
โ App.js ( ์์น: linkservice/client/src/App.js )
---------------------------------------------------------------------------------------------------
์ด์ App.js ์์ค๋ด์์๋ ReactKeycloakProvider์ initOptions ์ ์ ์ธํ๋ค.
onEvent={onKeycloakEvent} ๋ ์ ์ธํด๋ ๋๋, ๊ฐ๋ฐ์ ๋ชจ๋์์ refressToken๊ฐ ํ์ธ ์ฐจ์์์
๋ฐ์ํด ๋๋ค.
์์ ๋ App.js
import React from "react"
import { BrowserRouter, Route, Routes } from "react-router-dom"
import LinkMain from "./component/links"
import LinkCreateMain from "./component/links.create"
import ManagerHome from "./component/manager"
import MenuIcon from "./component/menu"
import LinksList from "./component/links.list"
import LinkEdit from "./component/links.edit"
import { ReactKeycloakProvider } from "@react-keycloak/web";
import keycloak, { onKeycloakEvent } from "./keycloak";
import PrivateRoute from "./PrivateRoute";
// import { onKeycloakEvent } from "./keycloak"
function App() {
return (
// ๊ธฐ์กด BrowserRouter ๋ฐ์ ReactKeycloakProvider๋ฅผ ์ ์ธํ๋ค.
// initOptions์ ์ํด์ http://localhost:3000 ์ผ๋ก ์ ์์ keycloak ๋ก๊ทธ์ธ ํ์ด์ง๋ก ์ด๋๋๋ค.
<ReactKeycloakProvider authClient={keycloak} onEvent={onKeycloakEvent} >
{/* initOptions={initOptions} > ์ ์ธ์ํจ๋ค. */}
<BrowserRouter>
<Routes>
<Route exact path="/" element={<LinkMain />} />
{/* PrivateRoute๋ฅผ ํตํด ๋ก๊ทธ์ธ์ด ๋ ์ํ์์๋ง ํ์ด์ง ์ ๊ทผ์ด ๊ฐ๋ฅํ๊ฒ ์ฒ๋ฆฌ */}
<Route exact path="/create" element={<PrivateRoute> <LinkCreateMain /> </PrivateRoute>} />
<Route exact path="/manager" element={<PrivateRoute> <ManagerHome /> </PrivateRoute>} />
<Route exact path="/links/list" element={<PrivateRoute> <LinksList /> </PrivateRoute>} />
<Route exact path="/link/edit/:id" element={<PrivateRoute> <LinkEdit /> </PrivateRoute>} />
</Routes>
<MenuIcon />
</BrowserRouter>
</ReactKeycloakProvider>
);
}
export default App;
โ index.js ( ์์น: linkservice/client/src/index.js )
---------------------------------------------------------------------------------------------------
๊ธฐ์กด index.js์์ <React.StrictMode> ๋ง ์ ์ธํ๋ค.
StrictMode๊ฐ ์์ผ๋ฉด http://localhost:3000 ์ ์์ ๋ฌดํ๋ก๋ฉ์ด ๋๋ฏ๋ก, ํด๋น StictMode๋ฅผ ๋นผ์ค๋ค.
์์ ๋ index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
// import './index.css';
import App from './App';
// import reportWebVitals from './reportWebVitals';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
// <React.StrictMode> ์ ์ธ์ํจ๋ค.
<App />
// </React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
// reportWebVitals();
๊ทธ๋ผ ์๋ฒ๋จ๊ณผ ํด๋ผ์ด์ธํธ๋จ์ ์คํํด์ ์ ์์ ์ผ๋ก ๋ฐ์์ด ๋์๋์ง ํ์ธํด๋ณด์.
์ ์์ ์ธ ํ์ด์ง๊ฐ ๋์จ๋ค๋ฉด ํ๋จ SettingIcon์ ํด๋ฆญํ๋ค.
ํ์ธ์ ๋๋ฅด๋ฉด Keycloak์ ๋ก๊ทธ์ธ ํ์ด์ง๊ฐ ๋์ค๋๊ฒ์ ํ์ธํ ์ ์๋ค.
๋ค์์๋ ๋ก๊ทธ์ธํ token๊ฐ ๋ฐ ๋ก๊ทธ์ธ ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ค๋๊ฒ์ ์์๋ณด์.
'ํตํฉ์ธ์ฆ์์คํ ๊ตฌ์ถ > KeyCloak' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Keycloak ๋ก๊ทธ์ธ ํ์ด์ง๋ฅผ ํตํด ๋ก๊ทธ์ธํ token ์ ๋ณด์ ์ฌ์ฉ์ ์ ๋ณด๋ฅผ ํ์ธ (0) | 2024.02.28 |
---|---|
React ํ์ด์ง์์ SSO(Keycloak)๋ก๊ทธ์ธ ์ฒ๋ฆฌํ๊ธฐ (0) | 2023.05.17 |
Keycloak ์ฌ์ฉ์ ์์ด๋์ ํด๋ผ์ด์ธํธ ์์ฑ (1) | 2023.05.10 |
KeyCloak ์ค์น ๋ฐ ๊ตฌ์ฑ (0) | 2023.05.08 |
Open Source Single Sing-On์ ๋ํด์ ์์๋ณด์ (0) | 2023.05.06 |