diff --git a/package.json b/package.json index bcd1b5ca..a16fb9b0 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@octokit/rest": "^18.0.12", "@types/validator": "^13.1.3", "axios": "^0.19.2", + "swr": "^0.3.11", "date-fns": "^2.16.1", "docsearch.js": "^2.6.3", "eventemitter3": "^4.0.4", diff --git a/pages/[username]/index.tsx b/pages/[username]/index.tsx index 9c716117..b9ef37df 100644 --- a/pages/[username]/index.tsx +++ b/pages/[username]/index.tsx @@ -30,7 +30,7 @@ const UserPage = () => { const router = useRouter() const username = router.query.username const nav = router.query.nav - const session = useSession() + const {session} = useSession() const [user, setUser]: [User, any] = useState(null) const [tags, setTags]: [Tag[], any] = useState([]) const [tagFilter, setTagFilter]: [string, any] = useState("") diff --git a/pages/_app.tsx b/pages/_app.tsx index 7537a227..f00880f1 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -20,10 +20,6 @@ const App = ({ Component, pageProps }) => { const seo = getSeo({ omitOpenGraphImage: false }) useEffect(() => { - requestApi.get(`/user/session`).then(res => { - events.emit('set-session', res.data) - }) - initUIConfig() }, []) diff --git a/pages/login/[code].tsx b/pages/login/[code].tsx index a8b848df..baefe395 100644 --- a/pages/login/[code].tsx +++ b/pages/login/[code].tsx @@ -3,8 +3,10 @@ import React, { useEffect, useState } from "react" import { requestApi } from "utils/axios/request" import { saveToken } from "utils/axios/getToken" import storage from "utils/localStorage" +import useSession from "hooks/use-session" const LoginCodePage = () => { + const {useLogin} = useSession() const router = useRouter() const code = router.query.code useEffect(() => { @@ -18,7 +20,7 @@ const LoginCodePage = () => { if (res.data) { //已经注册过 saveToken(res.data.token) - storage.set('session', res.data) + useLogin() const oldPage = storage.get('current-page') if (oldPage) { storage.remove('current-page') diff --git a/pages/login/index.tsx b/pages/login/index.tsx index 92b40087..0e591724 100644 --- a/pages/login/index.tsx +++ b/pages/login/index.tsx @@ -27,9 +27,11 @@ import { saveToken } from "utils/axios/getToken" import storage from "utils/localStorage" import { useRouter } from "next/router" import { validateEmail } from "utils/user" +import useSession from "hooks/use-session" const LoginPage = () => { + const {useLogin} = useSession() const { isOpen, onOpen, onClose } = useDisclosure() const toast = useToast() const router = useRouter() @@ -38,8 +40,8 @@ const LoginPage = () => { const login = async (email: string) => { const res = await requestApi.post("/user/login", { email: email }) saveToken(res.data.token) - storage.set('session', res.data) const oldPage = storage.get('current-page') + useLogin() if (oldPage) { storage.remove('current-page') router.push(oldPage) diff --git a/pages/login/onboard.tsx b/pages/login/onboard.tsx index b12dc7df..764e3b5c 100644 --- a/pages/login/onboard.tsx +++ b/pages/login/onboard.tsx @@ -11,8 +11,10 @@ import { ReserveUrls } from "src/data/reserve-urls" import { Tag } from "src/types/tag" import Follow from "components/interaction/follow" import { validateUsername } from "utils/user" +import useSession from "hooks/use-session" const OnboardPage = () => { + const {useLogin} = useSession() const [step,setStep] = useState(1) const [email,setEmail] = useState('') const [nickname,setNickname] = useState('') @@ -63,7 +65,6 @@ const OnboardPage = () => { } const res = await requestApi.post("/user/register", { code: code, nickname: nickname,username: username }) saveToken(res.data.token) - storage.set('session', res.data) setStep(2) const res1 = await requestApi.get(`/tag/all`) @@ -71,6 +72,7 @@ const OnboardPage = () => { } const finish = async () => { + useLogin() const oldPage = storage.get('current-page') if (oldPage) { storage.remove('current-page') diff --git a/pages/r/comment/[id].tsx b/pages/r/comment/[id].tsx index f0cdddbb..f40e6a26 100644 --- a/pages/r/comment/[id].tsx +++ b/pages/r/comment/[id].tsx @@ -8,7 +8,7 @@ import { Box, Button } from "@chakra-ui/react" const CommentPage = () => { const router = useRouter() - const session = useSession() + const {session} = useSession() const [comment,setComment]:[Comment,any] = useState(null) useEffect(() => { if (router.query.id) { diff --git a/pages/tags/[name].tsx b/pages/tags/[name].tsx index ef0c2546..9c57e7c6 100644 --- a/pages/tags/[name].tsx +++ b/pages/tags/[name].tsx @@ -59,15 +59,15 @@ const UserPage = () => { } }, [router.query.name]) - const session = useSession() + const {session} = useSession() const isModerator = () => { - if (isAdmin(session.user.role)) { + if (isAdmin(session?.user.role)) { return true } for (const m of moderators) { - if (m.id === session.user.id) { + if (m.id === session?.user.id) { return true } } @@ -141,7 +141,7 @@ const UserPage = () => { {moderators.length > 0 && Tag moderators - {isAdmin(session.user.role) && router.push(`/admin/tags`)}>{getSvgIcon('edit','.9rem')}} + {session && isAdmin(session.user.role) && router.push(`/admin/tags`)}>{getSvgIcon('edit','.9rem')}} {moderators.map(m => diff --git a/pages/tags/index.tsx b/pages/tags/index.tsx index 7fa63abd..16c45885 100644 --- a/pages/tags/index.tsx +++ b/pages/tags/index.tsx @@ -44,7 +44,7 @@ const TagsPage = () => { const [tags, setTags]: [Tag[], any] = useState([]) const [userTags,setUserTags]:[Tag[],any] = useState([]) - const session = useSession() + const {session} = useSession() const getTags = () => { requestApi.get(`/tag/all?filter=${filter.id}`).then((res) => setTags(res.data)).catch(_ => setTags([])) } diff --git a/server/internal/api/user.go b/server/internal/api/user.go index c6033f74..37a2fbf1 100644 --- a/server/internal/api/user.go +++ b/server/internal/api/user.go @@ -1,6 +1,7 @@ package api import ( + "fmt" "net/http" "strings" @@ -84,6 +85,7 @@ func UpdateUser(c *gin.Context) { } func GetSession(c *gin.Context) { + fmt.Println(("get session")) sess := user.GetSession(c) c.JSON(http.StatusOK, common.RespSuccess(sess)) } diff --git a/src/components/comments/comments.tsx b/src/components/comments/comments.tsx index b0513a8b..086878c9 100644 --- a/src/components/comments/comments.tsx +++ b/src/components/comments/comments.tsx @@ -17,7 +17,7 @@ export const Comments = ({storyID}: Props) => { const [editorVisible,setEditorVisible] = useState(false) const [sorter,setSorter] = useState(SearchFilter.Favorites) - const session = useSession() + const {session} = useSession() useEffect(() => { getComments() diff --git a/src/components/comments/editor.tsx b/src/components/comments/editor.tsx index 622f95ed..42d9a9b3 100644 --- a/src/components/comments/editor.tsx +++ b/src/components/comments/editor.tsx @@ -2,12 +2,10 @@ import React, { useState } from "react" import { Box, Text, Flex, HStack, useColorModeValue, Button, VStack, Avatar, Heading, propNames } from "@chakra-ui/react" import Card from "components/card" import { MarkdownEditor } from "components/markdown-editor/editor" -import useSession from "hooks/use-session" import { getUserName } from "utils/user" import EditModeSelect from "components/edit-mode-select" import { EditMode } from "src/types/editor" import { MarkdownRender } from "components/markdown-editor/render" -import { Comment } from "src/types/comments" import { User } from "src/types/user" interface Props { diff --git a/src/components/story/story-sidebar.tsx b/src/components/story/story-sidebar.tsx index 81315e36..69933cf0 100644 --- a/src/components/story/story-sidebar.tsx +++ b/src/components/story/story-sidebar.tsx @@ -21,7 +21,7 @@ interface Props { export const StorySidebar = (props: Props) => { const {story,vertical = true} = props - const session = useSession() + const {session} = useSession() const router = useRouter() const getEditUrl = () => { if (story.type === IDType.Post) { diff --git a/src/components/user-menu.tsx b/src/components/user-menu.tsx index 49ce491d..628a7214 100644 --- a/src/components/user-menu.tsx +++ b/src/components/user-menu.tsx @@ -10,21 +10,19 @@ import { Button } from "@chakra-ui/react" import useSession from "hooks/use-session" -import { Session } from "src/types/user" import { useRouter } from "next/router" import storage from "utils/localStorage" import { ReserveUrls } from "src/data/reserve-urls" import { FaRegSun, FaUserAlt ,FaBookmark, FaSignOutAlt,FaEdit,FaStar, FaHeart, FaThLarge} from "react-icons/fa" import { isAdmin, isEditor } from "utils/role" -import { logout } from "utils/session" + import Link from "next/link" export const UserMenu = () => { - const session: Session = useSession() + const {session,logout} = useSession() const router = useRouter() const login = () => { - console.log(router) storage.set("current-page", router.asPath) router.push(ReserveUrls.Login) } diff --git a/src/hooks/use-session.ts b/src/hooks/use-session.ts index 371acc52..5719718f 100644 --- a/src/hooks/use-session.ts +++ b/src/hooks/use-session.ts @@ -1,31 +1,33 @@ import { useEffect, useState } from "react" -import { Session } from "src/types/user" import { requestApi } from "utils/axios/request" -import events from "utils/events" -import storage from "utils/localStorage" +import useSWR from 'swr' -function useSession(): Session{ - const [session, setSession] = useState(null) +export const useSession = () => { + const [session,setSession] = useState(null) + const { data, revalidate } = useSWR( + '/user/session', + () => + requestApi.get(`/user/session`).then(res => { + return res.data + }), + {dedupingInterval: 60000} + ) + useEffect(() => { - const sess = storage.get('session') - if (sess) { - setSession(sess) - } - - events.on('set-session',storeSession) - - return() => { - events.off('set-session',storeSession) - } - }, []) - + setSession(data) + },[data]) + + const useLogin = async () => { + revalidate() + } - const storeSession = (sess: Session) => { - sess ? storage.set('session', sess) : storage.remove('session') - setSession(sess) + const logout = async () => { + await requestApi.post("/user/logout") + setSession(null) } - return session + return {session,useLogin,logout} } -export default useSession + +export default useSession \ No newline at end of file diff --git a/src/utils/axios/request.ts b/src/utils/axios/request.ts index 4c840d12..4fbc3916 100644 --- a/src/utils/axios/request.ts +++ b/src/utils/axios/request.ts @@ -17,7 +17,6 @@ const JSONbigString = require('json-bigint')({ storeAsString: true }) import type { OutgoingHttpHeaders } from 'http' import { createStandaloneToast } from "@chakra-ui/react" -import { logout } from 'utils/session' import { getToken } from './getToken' const toast = createStandaloneToast() @@ -68,12 +67,7 @@ requestApi.interceptors.response.use( message = error.text ?? error.message } - if (status === 401) { - if (getToken()) { - // 当前登录状态已经过期,进行登出操作 - logout() - } - } else { + if (status !== 401) { toast({ title: `请求错误`, description: message, diff --git a/yarn.lock b/yarn.lock index bc584d89..8c9f33a7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1836,6 +1836,11 @@ deprecation@^2.0.0, deprecation@^2.3.1: resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== +dequal@2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.2.tgz#85ca22025e3a87e65ef75a7a437b35284a7e319d" + integrity sha512-q9K8BlJVxK7hQYqa6XISGmBZbtQQWVXSrRrWreHC94rMt1QL/Impruc+7p2CYSYuVIUr+YCt6hjrs1kkdJRTug== + des.js@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" @@ -3724,6 +3729,13 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" +swr@^0.3.11: + version "0.3.11" + resolved "https://registry.yarnpkg.com/swr/-/swr-0.3.11.tgz#f7f50ed26c06afea4249482cec504768a2272664" + integrity sha512-ya30LuRGK2R7eDlttnb7tU5EmJYJ+N6ytIOM2j0Hqs0qauJcDjVLDOGy7KmFeH5ivOwLHalFaIyYl2K+SGa7HQ== + dependencies: + dequal "2.0.2" + through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5"