참고
- https://www.npmjs.com/package/react-comments-section
- https://riyanegi.github.io/react-comments-documentation/
- Toast UI Editor with OAuth to Access GitHub
- GitHub OAuth 인증 토큰으로 로그인 상태 관리하기
- 댓글 기능 만들기 with react-comments-section
- 로그인한 사용자만 댓글 기능 사용하기
- GitHub RESTful API로 댓글 저장하기
- 리액트 쿠키로 GitHub OAuth 로그인 인증 관리하기
- Mui Pagination으로 댓글 페이지로 나누기
react-comments-section의 Component에서 currentUser를 null로 설정해보자.
let currentUser = null;
// let currentUser = {
// currentUserId: "01a",
// currentUserImg:
// "https://ui-avatars.com/api/name=Riya&background=random",
// currentUserProfile:
// "https://www.linkedin.com/in/riya-negi-8879631a9/",
// currentUserFullName: "Riya Negi",
// };
...
<CommentSection
currentUser={currentUser}
logIn={{
loginLink: "http://localhost:3001/",
signupLink: "http://localhost:3001/",
}}
...
/>
사용자 정보가 없는 경우 Log In과 Sign Up 버튼이 나타나게 되고, 클릭하면 login에 설정한 링크로 이동하게 된다.
로그인 버튼을 클릭하면 로그인이 되어 댓글을 남길 수 있도록 해보자.
깃허브 로그인 기능 연동
- Toast UI Editor with OAuth to Access GitHub
- GitHub OAuth 인증 토큰으로 로그인 상태 관리하기
위의 세 링크를 참고하여 코드를 추가해보자.
먼저 App.js에서 로그인 체크 함수를 실행하기 위해 githublibrary.js에서 아래와 같이 코드를 추가한다.
import axios from "axios";
export const loginCheck = async (setLoginStatus) => {
let token = localStorage.getItem("GITHUB_TOKEN");
try {
const response = await axios.get("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${token}`,
},
});
console.log(response);
setLoginStatus(true);
} catch (error) {
console.error("Error fetching user data:", error);
setLoginStatus(false);
}
};
App.js는 다음과 같다.
login 상태를 관리하는 변수와 현재 유저의 정보를 가지는 변수를 useState로 관리한다.
loginStatus가 true라면 LOGIN_ID와 AVATAR_URL, 그리고 profile URL을 설정한다.
그리고 currentUser를 ReactComments의 props로 넘겨준다.
import React, { useEffect, useState } from "react";
import { Route, Link, Routes } from "react-router-dom";
import "./App.css";
// ...
import ReactComments from "./page/ReactComments";
import GitHubLoginCallBack from "./page/GitHubLoginCallback";
import * as gh from "./githublibrary.js";
const App = () => {
const [loginStatus, setLoginStatus] = useState(false);
const [currentUser, setCurrentUser] = useState(null);
useEffect(() => {
if(loginStatus === false) return;
let loginID = localStorage.getItem("LOGIN_ID");
let url = localStorage.getItem("AVATAR_URL");
let profile = `https://github.com/${loginID}`;
setCurrentUser({
currentUserId: loginID,
currentUserImg: url,
currentUserProfile: profile,
currentUserFullName: loginID,
});
}, [loginStatus]);
useEffect(() => {
gh.loginCheck(setLoginStatus);
}, []);
return (
<div className="App">
<div className="router">
{...}
<span>
<Link to="/comments">Comments</Link>
</span>
</div>
<div>
<Routes>
{...}
<Route
path="/comments"
element={<ReactComments currentUser={currentUser} />}
/>
<Route
path="/callback"
element={
<GitHubLoginCallBack
loginStatus={loginStatus}
setLoginStatus={setLoginStatus}
/>
}
/>
</Routes>
</div>
</div>
);
};
export default App;
GitHubLoginCallback.js는 다음과 같다. (링크 참고)
import React, { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import axios from "axios";
import queryString from "query-string";
const clientID = process.env.REACT_APP_CLIENT_ID;
const GitHubLoginCallback = ({ loginStatus, setLoginStatus }) => {
const navigate = useNavigate();
const getAccessToken = async (code) => {
try {
let server = `http://192.168.55.120:3002`;
let accessInfo = await axios.get(
`${server}/githubLogin?code=${code}&clientID=${clientID}`
);
let token = accessInfo.data.token;
const userResponse = await axios.get("https://api.github.com/user", {
headers: {
Authorization: `Bearer ${token}`,
},
});
const userData = userResponse.data;
const avatarUrl = userData.avatar_url;
const loginID = userData.login;
console.log(userData);
console.log(avatarUrl);
console.log(loginID);
localStorage.setItem("GITHUB_TOKEN", token);
localStorage.setItem("AVATAR_URL", avatarUrl);
localStorage.setItem("LOGIN_ID", loginID);
setLoginStatus(true);
navigate('/', { replace: true });
} catch (e) {
console.log(e);
setLoginStatus(false);
}
};
const getCode = () => {
let qs = queryString.parse(window.location.search);
let code = qs.code;
getAccessToken(code);
};
useEffect(() => getCode(), []);
return <div>{loginStatus ? "로그인 성공!" : "로그인 실패..."}</div>;
};
export default GitHubLoginCallback;
ReactComments는 깃허브 로그인을 위해 loginURL을 설정한다.
const clientID = process.env.REACT_APP_CLIENT_ID;
const callbackURL = "http://localhost:3000/callback";
const loginURL = `https://github.com/login/oauth/authorize?client_id=${clientID}&scope=repo:status read:repo_hook user:email&redirect_uri=${callbackURL}`;
위의 login 버튼을 누르면 loginURL로 이동하여 깃허브 로그인을 할 수 있게 된다.
그리고 signupLink는 깃허브 링크를 설정하였다.
<CommentSection
currentUser={getCurrentUser}
logIn={{
loginLink: loginURL,
signupLink: "https://github.com/",
}}
currentUser는 다음과 같이 얻는다.
/comments 라우터로 바로 이동할 경우, login 정보를 얻을 수 없기 때문에 추가한 방어코드다.
const getCurrentUser = () => {
if (currentUser === null) {
let loginID = localStorage.getItem("LOGIN_ID");
let url = localStorage.getItem("AVATAR_URL");
let profile = `https://github.com/${loginID}`;
if(loginID === null) return null;
return {
currentUserId: loginID,
currentUserImg: url,
currentUserProfile: profile,
currentUserFullName: loginID,
}
}
return currentUser;
};
ReactComments.js의 전체 코드는 다음과 같다.
import React from "react";
import { CommentSection } from "react-comments-section";
//import 'react-comments-section/dist/index.css';
import "../css/comment.css";
const clientID = process.env.REACT_APP_CLIENT_ID;
const callbackURL = "http://localhost:3000/callback";
const loginURL = `https://github.com/login/oauth/authorize?client_id=${clientID}&scope=repo:status read:repo_hook user:email&redirect_uri=${callbackURL}`;
const ReactComments = ({ currentUser }) => {
const data = [
{
userId: "02b",
comId: "017",
fullName: "Lily",
userProfile: "https://www.linkedin.com/in/riya-negi-8879631a9/",
text: "I think you have a point🤔",
avatarUrl: "https://ui-avatars.com/api/name=Lily&background=random",
replies: [],
},
];
const onSubmitAction = (data) => {
console.log("check submit, ", data);
};
// const onDeleteAction
// const onReplyAction
// const onEditAction
const currentData = (data) => {
console.log("current data", data);
};
const getCurrentUser = () => {
if (currentUser === null) {
let loginID = localStorage.getItem("LOGIN_ID");
let url = localStorage.getItem("AVATAR_URL");
let profile = `https://github.com/${loginID}`;
if(loginID === null) return null;
return {
currentUserId: loginID,
currentUserImg: url,
currentUserProfile: profile,
currentUserFullName: loginID,
}
}
return currentUser;
};
return (
<div>
<CommentSection
currentUser={getCurrentUser}
logIn={{
loginLink: loginURL,
signupLink: "https://github.com/",
}}
commentData={data}
currentData={currentData}
onSubmitAction={onSubmitAction}
hrStyle={{ border: "0.5px solid #ff0072" }}
inputStyle={{ border: "1px solid rgb(208 208 208)" }}
formStyle={{ backgroundColor: "white" }}
submitBtnStyle={{
border: "1px solid black",
backgroundColor: "black",
padding: "7px 15px",
}}
cancelBtnStyle={{
border: "1px solid gray",
backgroundColor: "gray",
color: "white",
padding: "7px 15px",
}}
replyInputStyle={{ borderBottom: "1px solid black", color: "black" }}
advancedInput={true}
removeEmoji={false}
/>
</div>
);
};
export default ReactComments;
로컬에서 로그인이 정상적으로 이루어지는지 테스트해보자.
'개발 > React' 카테고리의 다른 글
리액트 - 쿠키로 GitHub OAuth 로그인 인증 관리하기 with react-cookie (0) | 2023.11.15 |
---|---|
리액트 - GitHub RESTful API로 댓글 저장하기 with react-comments-section (0) | 2023.11.15 |
리액트 - 댓글 기능 만들기 with react-comments-section (React Comments and Reply) (0) | 2023.11.15 |
리액트 - Handsontable 깃허브 연동하기 (data, style, comment, merge 저장하기) (1) | 2023.09.30 |
리액트 - Handsontable 셀 스타일 로컬 스토리지에 저장하기 (전체 코드) (0) | 2023.09.30 |
댓글