auth & cache
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
summerizer.py
|
||||||
4
Dockerfile
Normal file
4
Dockerfile
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FROM ubuntu:latest
|
||||||
|
LABEL authors="hzhang"
|
||||||
|
|
||||||
|
ENTRYPOINT ["top", "-b"]
|
||||||
20
package-lock.json
generated
20
package-lock.json
generated
@@ -9,6 +9,7 @@
|
|||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"oidc-client-ts": "^3.1.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.0.1"
|
"react-router-dom": "^7.0.1"
|
||||||
@@ -4521,6 +4522,14 @@
|
|||||||
"node": ">=6"
|
"node": ">=6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jwt-decode": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/kind-of": {
|
"node_modules/kind-of": {
|
||||||
"version": "6.0.3",
|
"version": "6.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
|
||||||
@@ -4829,6 +4838,17 @@
|
|||||||
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
|
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/oidc-client-ts": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/oidc-client-ts/-/oidc-client-ts-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-IDopEXjiwjkmJLYZo6BTlvwOtnlSniWZkKZoXforC/oLZHC9wkIxd25Kwtmo5yKFMMVcsp3JY6bhcNJqdYk8+g==",
|
||||||
|
"dependencies": {
|
||||||
|
"jwt-decode": "^4.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/on-finished": {
|
"node_modules/on-finished": {
|
||||||
"version": "2.4.1",
|
"version": "2.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"oidc-client-ts": "^3.1.0",
|
||||||
"react": "^18.3.1",
|
"react": "^18.3.1",
|
||||||
"react-dom": "^18.3.1",
|
"react-dom": "^18.3.1",
|
||||||
"react-router-dom": "^7.0.1"
|
"react-router-dom": "^7.0.1"
|
||||||
|
|||||||
30
src/AuthProvider.js
Normal file
30
src/AuthProvider.js
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import React, { createContext, useEffect, useState } from "react";
|
||||||
|
import { UserManager } from "oidc-client-ts";
|
||||||
|
import {oidcConfig} from "./oicdConfig";
|
||||||
|
|
||||||
|
|
||||||
|
export const AuthContext = createContext();
|
||||||
|
|
||||||
|
const AuthProvider = ({ children }) => {
|
||||||
|
const [user, setUser] = useState(null);
|
||||||
|
const userManager = new UserManager(oidcConfig);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
userManager.getUser().then((user) => {
|
||||||
|
if (user && !user.expired) {
|
||||||
|
setUser(user);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [userManager]);
|
||||||
|
|
||||||
|
const login = () => userManager.signinRedirect();
|
||||||
|
const logout = () => userManager.signoutRedirect();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<AuthContext.Provider value={{ user, login, logout }}>
|
||||||
|
{children}
|
||||||
|
</AuthContext.Provider>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AuthProvider;
|
||||||
17
src/Callback.js
Normal file
17
src/Callback.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import React, { useEffect } from "react";
|
||||||
|
import { UserManager } from "oidc-client-ts";
|
||||||
|
import {oidcConfig} from "./oicdConfig";
|
||||||
|
|
||||||
|
|
||||||
|
const Callback = () => {
|
||||||
|
useEffect(() => {
|
||||||
|
const userManager = new UserManager(oidcConfig);
|
||||||
|
userManager.signinRedirectCallback().then(() => {
|
||||||
|
window.location.href = "/";
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return <div>Logging in...</div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Callback;
|
||||||
@@ -1,16 +1,28 @@
|
|||||||
//src/components/MainNavigation.js
|
//src/components/MainNavigation.js
|
||||||
|
|
||||||
import React from "react";
|
import React, {useContext} from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import "./MainNavigation.css";
|
import "./MainNavigation.css";
|
||||||
|
import {AuthContext} from "../AuthProvider";
|
||||||
|
|
||||||
const MainNavigation = () => {
|
const MainNavigation = () => {
|
||||||
|
const { user, login, logout } = useContext(AuthContext);
|
||||||
return (
|
return (
|
||||||
<nav className="main-navigation">
|
<nav className="main-navigation">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li>
|
||||||
<Link to="/">Home</Link>
|
<Link to="/">Home</Link>
|
||||||
</li>
|
</li>
|
||||||
|
{user ? (
|
||||||
|
<div>
|
||||||
|
<h1>{user.profile.name}</h1>
|
||||||
|
<button onClick={logout}>Logout</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<button onClick={login}>Login</button>
|
||||||
|
)
|
||||||
|
|
||||||
|
}
|
||||||
<li>
|
<li>
|
||||||
<Link to="/login">Login</Link>
|
<Link to="/login">Login</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
8
src/oicdConfig.js
Normal file
8
src/oicdConfig.js
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
export const oidcConfig = {
|
||||||
|
authority: "https://login.hangman-lab.top/auth/realms/myrealm",
|
||||||
|
client_id: "your-client-id",
|
||||||
|
redirect_uri: "http://localhost:3000/callback",
|
||||||
|
post_logout_redirect_uri: "http://localhost:3000",
|
||||||
|
response_type: "code",
|
||||||
|
scope: "openid profile email",
|
||||||
|
};
|
||||||
@@ -1,4 +1,10 @@
|
|||||||
|
const ongoingRequests = new Map();
|
||||||
|
|
||||||
export async function fetchWithCache(url, cacheKey = url, cacheExpiry = 60) {
|
export async function fetchWithCache(url, cacheKey = url, cacheExpiry = 60) {
|
||||||
|
if (ongoingRequests.has(url)) {
|
||||||
|
return ongoingRequests.get(url);
|
||||||
|
}
|
||||||
|
|
||||||
const cachedData = localStorage.getItem(cacheKey);
|
const cachedData = localStorage.getItem(cacheKey);
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
@@ -12,13 +18,23 @@ export async function fetchWithCache(url, cacheKey = url, cacheExpiry = 60) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url);
|
try {
|
||||||
if (!response.ok) {
|
const fetchPromise = fetch(url)
|
||||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
.then((response) => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then((data) => {
|
||||||
|
localStorage.setItem(cacheKey, JSON.stringify({ data, timestamp: now }));
|
||||||
|
ongoingRequests.delete(url);
|
||||||
|
return data;
|
||||||
|
});
|
||||||
|
ongoingRequests.set(url, fetchPromise);
|
||||||
|
return await fetchPromise;
|
||||||
|
} catch (error) {
|
||||||
|
ongoingRequests.delete(url);
|
||||||
|
throw error;
|
||||||
}
|
}
|
||||||
const data = await response.json();
|
|
||||||
|
|
||||||
localStorage.setItem(cacheKey, JSON.stringify({ data, timestamp: now }));
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user