Skip to content

Commit

Permalink
Merge pull request #81 from YAPP-Github/feat/MAFOO-92
Browse files Browse the repository at this point in the history
[feat/MAFOO-92] 로그인 토큰 기간 정의 및 서버에서 쿠키 관리
  • Loading branch information
minsu-zip authored Aug 12, 2024
2 parents c0a6ca5 + 4e16e1b commit e011f52
Show file tree
Hide file tree
Showing 18 changed files with 118 additions and 87 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
"class-variance-authority": "^0.7.0",
"clsx": "^2.1.1",
"eslint-plugin-simple-import-sort": "^12.1.0",
"js-cookie": "^3.0.5",
"lucide-react": "^0.390.0",
"next": "14.2.3",
"next-auth": "5.0.0-beta.20",
Expand Down
9 changes: 0 additions & 9 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/app/album/create/hooks/useAlbum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import { useRouter } from "next/navigation"

import { postAlbum } from "@/app/api/photo"
import { getQueryClient } from "@/common/QueryProviders"
import { useAlert } from "@/store/AlertContext"
import { useAlertStore } from "@/store/alert"

import { usePatchPhotoAlbum } from "../../../scanner/hooks/usePhoto"
import type { AlbumType } from "../../types"

export const usePostAlbum = () => {
const { showAlert } = useAlert()
const { showAlert } = useAlertStore()
const router = useRouter()
const { patchPhotoAlbum } = usePatchPhotoAlbum()

Expand Down
10 changes: 6 additions & 4 deletions src/app/api/myfetch/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getAccessToken } from "@/libs"
import { useAuthStore } from "@/store/auth"

import customFetch from "./customFetch"

Expand All @@ -13,10 +13,12 @@ export const myFetch = customFetch({
request: async ([url, options], fetch) => {
// 요청 인터셉터 로직 추가 (예: 로깅, 인증 토큰 추가)
// console.log("Request Interceptor:", url, options)
const token = getAccessToken()
if (token && options) {

const { accessToken } = useAuthStore.getState()

if (accessToken && options) {
const headers = new Headers(options.headers || {})
headers.set("Authorization", `Bearer ${token}`)
headers.set("Authorization", `Bearer ${accessToken}`)
options.headers = headers
}
return [url, options]
Expand Down
16 changes: 11 additions & 5 deletions src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import "@/styles/main.css"

import type { Metadata } from "next"
import { cookies } from "next/headers"

import AuthProvider from "@/common/AuthProvider"
import ErrorHandlingWrapper from "@/common/ErrorHandlingWrapper"
import NextAuthProvider from "@/common/NextAuthProvider"
import { QueryProviders } from "@/common/QueryProviders"
import { ACCESS_TOKEN_KEY } from "@/constants"
import { pretendard } from "@/font"
import AlertContainer from "@/store/AlertContext"
import { AlertProvider } from "@/store/alert"
import { AuthProvider } from "@/store/auth"

export const metadata: Metadata = {
title: "마푸-네컷사진 전용 앨범",
Expand Down Expand Up @@ -41,17 +44,20 @@ export default function RootLayout({
}: Readonly<{
children: React.ReactNode
}>) {
const accessToken = cookies().get(ACCESS_TOKEN_KEY)?.value || null

return (
<html lang="ko" className={`${pretendard}`}>
<body className={pretendard.className}>
<AuthProvider>
<NextAuthProvider>
<QueryProviders>
<ErrorHandlingWrapper>
<AlertContainer />
<AlertProvider />
<AuthProvider accessToken={accessToken} />
{children}
</ErrorHandlingWrapper>
</QueryProviders>
</AuthProvider>
</NextAuthProvider>
</body>
</html>
)
Expand Down
4 changes: 2 additions & 2 deletions src/app/profile/_components/ListItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import Button from "@/common/Button"
import Icon from "@/common/Icon"
import { LIST_ITEM_INFO } from "@/constants"
import { isExternalLink, isInternalLink } from "@/libs"
import { useAlert } from "@/store/AlertContext"
import { useAlertStore } from "@/store/alert"

interface ItemButtonType {
label: string
Expand All @@ -21,7 +21,7 @@ export interface ListItemProps {

const ListItem = () => {
const router = useRouter()
const { showAlert } = useAlert()
const { showAlert } = useAlertStore()

const handleClick = async (item: ItemButtonType) => {
if (item.action) {
Expand Down
4 changes: 2 additions & 2 deletions src/app/scanner/hooks/usePhoto.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { useMutation, useQuery } from "@tanstack/react-query"

import { getAlbums, patchPhotoAlbum, postQrCode } from "@/app/api/photo"
import { useAlert } from "@/store/AlertContext"
import { useAlertStore } from "@/store/alert"

export const usePostQrCode = () => {
const { showAlert } = useAlert()
const { showAlert } = useAlertStore()

const { data, mutate, isPending } = useMutation({
mutationFn: (code: string) => postQrCode(code),
Expand Down
10 changes: 9 additions & 1 deletion src/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import KakaoProvider from "next-auth/providers/kakao"
import { authLogin } from "@/app/api/signIn"
import { ACCESS_TOKEN_KEY } from "@/constants"

import { useAuthStore } from "./store/auth"

export const {
handlers: { GET, POST },
auth,
Expand All @@ -26,7 +28,12 @@ export const {
if (account?.access_token) {
const authResponse = await authLogin(account.access_token)

cookies().set(ACCESS_TOKEN_KEY, authResponse.accessToken)
cookies().set(ACCESS_TOKEN_KEY, authResponse.accessToken, {
httpOnly: true,
sameSite: "lax",
path: "/",
maxAge: 30 * 24 * 60 * 60, // 30일
})

const updatedAccount = {
...account,
Expand Down Expand Up @@ -58,6 +65,7 @@ export const {
events: {
signOut() {
cookies().delete(ACCESS_TOKEN_KEY)
useAuthStore.getState().clearAuth()
return
},
},
Expand Down
18 changes: 0 additions & 18 deletions src/common/AuthProvider.tsx

This file was deleted.

14 changes: 14 additions & 0 deletions src/common/NextAuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"use client"

import { SessionProvider } from "next-auth/react"
import React from "react"

interface Props {
children: React.ReactNode
}

const NextAuthProvider = ({ children }: Props) => {
return <SessionProvider>{children}</SessionProvider>
}

export default NextAuthProvider
6 changes: 0 additions & 6 deletions src/libs/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
import Cookies from "js-cookie"

import { ACCESS_TOKEN_KEY } from "@/constants"

export const getAccessToken = () => Cookies.get(ACCESS_TOKEN_KEY)

// 하루 필름인 경우는 지점별 도메인이 가변적
// HARUFILM: "http://haru{숫자}.mx{숫자}.co.kr",

Expand Down
37 changes: 0 additions & 37 deletions src/store/AlertContext.tsx

This file was deleted.

14 changes: 14 additions & 0 deletions src/store/alert/AlertProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"use client"

import Alert from "../../common/Alert"
import useAlertStore from "./useAlertStore"

const AlertProvider = () => {
const { title, description, visible, hideAlert } = useAlertStore()

if (!visible) return null

return <Alert title={title} description={description} onClose={hideAlert} />
}

export default AlertProvider
2 changes: 2 additions & 0 deletions src/store/alert/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AlertProvider } from "./AlertProvider"
export { default as useAlertStore } from "./useAlertStore"
20 changes: 20 additions & 0 deletions src/store/alert/useAlertStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { create } from "zustand"

interface AlertState {
title: string
description: string
visible: boolean
showAlert: (title: string, description: string) => void
hideAlert: () => void
}

const useAlertStore = create<AlertState>((set) => ({
title: "",
description: "",
visible: false,
showAlert: (title: string, description: string) =>
set({ title, description, visible: true }),
hideAlert: () => set({ visible: false }),
}))

export default useAlertStore
19 changes: 19 additions & 0 deletions src/store/auth/AuthProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"use client"

import useAuthStore from "./useAuthStore"

interface AuthContextProps {
accessToken: string | null
}

const AuthProvider = ({ accessToken }: AuthContextProps) => {
const setAccessToken = useAuthStore((state) => state.setAccessToken)

if (accessToken) {
setAccessToken(accessToken)
}

return null
}

export default AuthProvider
2 changes: 2 additions & 0 deletions src/store/auth/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as AuthProvider } from "./AuthProvider"
export { default as useAuthStore } from "./useAuthStore"
15 changes: 15 additions & 0 deletions src/store/auth/useAuthStore.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { create } from "zustand"

interface AuthState {
accessToken: string | null
setAccessToken: (token: string | null) => void
clearAuth: () => void
}

const useAuthStore = create<AuthState>((set) => ({
accessToken: null,
setAccessToken: (token) => set({ accessToken: token }),
clearAuth: () => set({ accessToken: null }),
}))

export default useAuthStore

0 comments on commit e011f52

Please sign in to comment.