Feat#97 Kakao Login oauth 구현#142
Conversation
- token을 cookie에 넣기 위함
|
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
There was a problem hiding this comment.
Summary of Changes
Hello @eunwoo-levi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces the complete Kakao social login functionality to the application. It establishes a secure authentication flow by handling authorization codes, exchanging them for access tokens, and storing these tokens as HttpOnly cookies. The changes span across the frontend and a new Next.js API route, ensuring a robust and user-friendly login experience with appropriate error handling and UI feedback.
Highlights
- Kakao Social Login Implementation: I've implemented the full Kakao social login authentication flow, covering the user's redirection to Kakao, handling the authorization code callback, and processing it on the server side.
- Secure Token Handling: The access token received from the backend after successful Kakao authentication is now securely stored as an HttpOnly cookie. This enhances security by mitigating Cross-Site Scripting (XSS) vulnerabilities.
- Authentication Flow and UI Feedback: I've established a Next.js API route (
/api/auth/kakao-auth-code) to act as an intermediary for the authorization code exchange with the backend. The frontend now includes dedicated pages and hooks to manage the authentication process, display loading states, and provide user-friendly error messages for both successful and failed login attempts. - Axios Configuration for Cookie-Based Auth: The global Axios instance (
api.ts) has been configured withwithCredentials: true. This ensures that cookies, including the HttpOnly access token, are automatically sent with cross-origin requests to support the cookie-based authentication mechanism.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
📝 추가 및 변경된 파일총 5개 파일 변경 |
✅ Mosu Admin 빌드가 성공적으로 완료되었습니다!📋 빌드 결과
🚀 다음 단계코드 리뷰 후 머지하면 프로덕션에 배포됩니다. |
There was a problem hiding this comment.
Code Review
This pull request implements the Kakao OAuth login flow. I've found a few critical and high-severity issues that need to be addressed, including a method mismatch in an API route, and unsafe access to environment variables. I've also included some suggestions to improve code quality and user experience.
| if (req.method !== "GET") { | ||
| return res.status(405).json({ message: "Method Not Allowed. Use GET." }); | ||
| } |
There was a problem hiding this comment.
The API route is configured to only accept GET requests. However, the client-side useKakaoAuth hook sends a POST request. This will cause the request to fail with a 405 Method Not Allowed error. The handler should be updated to accept POST requests.
| if (req.method !== "GET") { | |
| return res.status(405).json({ message: "Method Not Allowed. Use GET." }); | |
| } | |
| if (req.method !== "POST") { | |
| return res.status(405).json({ message: "Method Not Allowed. Use POST." }); | |
| } |
| const { code } = req.query; | ||
| if (!code || typeof code !== "string") { | ||
| return res.status(400).json({ message: "Authorization code is required." }); | ||
| } |
There was a problem hiding this comment.
The API route is configured to read the authorization code from the query string (req.query). However, the client-side useKakaoAuth hook sends a POST request with the code in the request body. This will cause the request to fail. To fix this, read the code from req.body.
| const { code } = req.query; | |
| if (!code || typeof code !== "string") { | |
| return res.status(400).json({ message: "Authorization code is required." }); | |
| } | |
| const { code } = req.body; | |
| if (!code || typeof code !== "string") { | |
| return res.status(400).json({ message: "Authorization code is required." }); | |
| } |
| setError(null); | ||
| hasProcessedCode.current = code; | ||
|
|
||
| await api.post("/auth/kakao-auth-code", { code }); |
There was a problem hiding this comment.
The API call is made to /auth/kakao-auth-code. However, Next.js API routes under pages/api/ are accessed with an /api prefix. The correct endpoint is /api/auth/kakao-auth-code.
| await api.post("/auth/kakao-auth-code", { code }); | |
| await api.post("/api/auth/kakao-auth-code", { code }); | |
| router.push(redirectTo); |
| const KAKAO_CLIENT_ID = process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY!; | ||
| const REDIRECT_URI = process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI!; | ||
|
|
||
| const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`; |
There was a problem hiding this comment.
Using the non-null assertion operator (!) on environment variables is unsafe and can lead to runtime crashes if the variables are not set. A safer approach is to read the variables without assertion and then build the kakaoAuthUrl conditionally.
const KAKAO_CLIENT_ID = process.env.NEXT_PUBLIC_KAKAO_REST_API_KEY;
const REDIRECT_URI = process.env.NEXT_PUBLIC_KAKAO_REDIRECT_URI;
const kakaoAuthUrl =
KAKAO_CLIENT_ID && REDIRECT_URI
? `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`
: "";| 잠시 후 다시 시도해주세요. | ||
| </p> | ||
| <button | ||
| onClick={() => window.location.href = "/auth/member/signin"} |
There was a problem hiding this comment.
| return ( | ||
| <div className="p-5 text-center"> | ||
| <p>로그인 처리 중입니다...</p> | ||
| </div> | ||
| ); |
There was a problem hiding this comment.
The UI for the isLoading state and the default return state (which acts as a loading state before redirection) are identical. This leads to duplicated code. You can simplify this by combining the conditions.
if (isLoading || !error) {
return (
<div className="p-5 text-center">
<p>로그인 처리 중입니다...</p>
</div>
);
}
return null;
📚 Storybook이 Chromatic에 배포되었습니다!
|
| 잠시 후 다시 시도해주세요. | ||
| </p> | ||
| <button | ||
| onClick={() => window.location.href = "/auth/member/signin"} |
There was a problem hiding this comment.
여기에 window.location.href를 쓴 이유가 따로 있을까요?
There was a problem hiding this comment.
kakao redirect로직 이어서 짜다가 당시에 무의식적으로 짠 것 같습니다. 해당 부분은 같은 도메인에서 이동하기 때문에 더 효율적인 라우팅을 위해 router를 쓰는게 낫겠네요! 짚어주셔서 감사합니다!
| const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`; | ||
|
|
There was a problem hiding this comment.
가능하면 경로는 상수처리하는게 관리하기 편할거같아요~
| const kakaoAuthUrl = `https://kauth.kakao.com/oauth/authorize?client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`; | |
| const kakaoAuthUrl = `NEXT_PUBLIC_KAKAO_REDIRECT_URI?client_id=${KAKAO_CLIENT_ID}&redirect_uri=${REDIRECT_URI}&response_type=code`; |
✅ Linked Issue
🔍 What I did
💡 Why I did it
withCredentials: true적용하여 쿠키 기반 인증 지원Oauth Flow
🚧 TODO (if any)