미루고 미루다가 100DaysOfCode 챌린지를 시작했다. github repo에도 매일 간단히 로그를 업데이트 하지만, 나중에 따로 포스팅할 것들을 기억하기 위해 velog에도 글을 작성하려고 한다.
100 days of code 챌린지는 말 그대로 100일동안 매일 코딩을 하는 챌린지이고 하루에 최소 한 시간씩 하는 것이 주요 룰이다. 더 자세한 내용은 공식사이트에서 확인해볼 수 있으며, 이미 친절하신 분께서 한글로 번역한 글도 있다.
챌린지 하고 계신 분이 있다면 댓글이나 트위터 팔로우 부탁드립니다👍 같이 열심히 해봐요
NextAuth.js
를 이용해 Next.js 프로젝트에 GitHub 계정으로 로그인하는 기능을 추가했다. 내가 사용한 버전은 v3 이고 처음에 베타버전인 v4 docs를 보느라 헛수고를 했다.
깃허브 - Settings - Developer settings - GitHub Apps 에서 New GitHub App 을 만들어준다.
Hompage URL : http://localhost:3000
Callback URL: http://localhost:3000/api/auth/callback/github
그리고 permission을 본인의 프로젝트에 맞게 설정하면 된다.
앱이 만들면 Client ID 가 생성되고 Client secret를 생성한다. /pages/api/auth/[...nextauth].js
import NextAuth from "next-auth";
import Providers from "next-auth/providers";
export default NextAuth({
providers: [
Providers.GitHub({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
});
참고
NextAuth로 깃헙 provider만 설정하면 모든 게 술술 풀릴 줄 알았다. 하지만 세션에는 기본적인 사용자 정보만 있다. 유저의 저장소 등은 GitHub REST API 를 사용해야 한다. 이를 위해서 오늘은
등을 공부했다. 그리고 CSRF 토큰에 대해서 개념이 잡혀있지 않아서, 초반에 Octokit auth에 계속 이 토큰 값을 넘기는 삽질을 했다. 당연히 안된다. 왜냐하면 Octokit은 github access token 값을 필요로 하기 때문이다. Cross Site Request Forgery랑 전혀 관련이 없다. 어쨌든 provider의 callback 함수를 이용하여 문제를 해결했다. 드디어 사용자의 모든 저장소들(비공개 저장소 포함)을 불러올 수 있게 되었다.
참고
오늘은 조금 쉬어가는 느낌으로 단순 그리드, 툴팁 추가 작업을 했다. 10x10 grid를 만들고 각 element마다 hover시 tooltip을 보여주는 작업을 했는데, 각 element 마다 tooltip이 100개씩 뜨는 버그가 있어서 수정했다. react-tooltip
패키지를 사용했는데, data-for 과 id 값을 제대로 매치하지 않아서 일어난 버그같다.
내가 구현하려던 기능은 github 계정으로 로그인 해서 비공개 저장소까지 본인이 owner인 저장소들을 모두 불러오는 것이었다. 그런데 분명 인증이 되어있는데도 public 저장소만 불러오는게 아닌가? 그래서 원인을 분석해봤는데, 일단 지금까지 내 생각에는 day1에 언급했던것처럼 github app을 사용한게 문제인 것 같다. 그래서 oauth app을 대신 사용하니 해결되었다. 문제는 유저의 private 저장소까지 불러오기 위해 scope를 설정했는데, repo
외에는 제대로 동작되는 scpe가 없었다. 그런데 그냥 repo
를 사용하면 organization 에 승인 요청을 할거냐는 메세지가 뜨는데, 내가 organization에 승인 요청을 하지 않는 이상 알람이 갈 것 같지는 않지만 거슬린다. organization 과 관련된 저장소는 아예 불러오지 않을 프로젝트인데..
GitHub for VSCode은 안그런데, 내가 scope 설정을 잘못했나?
프로젝트를 진행하다보니 데이터베이스가 필요하다는 걸 깨달았다. 이를 통해서 다시 Authentication 부터 수정하고 있다. MongoDB를 사용할 것이고, 우선 유저가 깃허브 계정을 통해서 로그인을 했을 때 유저 정보를 데이터베이스에 저장하는 것 부터 구현해야한다. 이를 위해서 Next.js 앱과 MongoDB를 연동하는 것을 공부했는데, 여기에 잘 설명되어있어서 도움이 되었다. 물론 이 글만 보고 했을 때 동작하지 않는 것들이 있어서 조금 수정을 하긴 했지만. (수정 후 동작하는 것들은 여기에 올렸다.)
이제 문제는 NextAuth provider에 adapter로 MongoDB Adapter를 추가해야하는데, 계속 알 수 없는 에러가 발생하고 있다는 것이다. 우선 오늘은 여기까지만 하고 내일 더 알아보려고한다.
참고
Day 5 에서 언급한 MongoDB Adapter 추가시 발생하던 문제는 알고보니 mongodb
버전 문제였다. 버전을 3.x로 변경하니 잘 된다. 그리고 조금 더 찾아본 결과 NextAuth.js v3 docs에 TypeORM adapter를 사용하는 방법이 잘 설명되어 있었다. 유저 정보가 잘 저장되는 것을 볼 수 있다.
참고
Day 6 에서 MongoDB 연동하고 유저 정보도 저장된다~ 하고 마음 편하게 테스트했는데 깃허브에서 저장소를 불러오는 코드가 안된다.
분석결과, 데이터베이스를 사용하기 전에는 아래와 같이 jwt callback에서 account에 저장된 github access token을 token에 저장하고 이를 session으로 넘겨주는 식으로 했었는데, 데이터베이스를 추가하면 이런 방식으로는 동작하지 않는다.
...
callbacks: {
session: async (session, token) => {
session.accessToken = token.githubAccessToken;
return session;
},
jwt: async (token, user, account, profile) => {
if (user && account && account.provider === "github") {
token.username = profile.login;
token.githubAccessToken = account.accessToken;
}
return Promise.resolve(token);
},
},
...
DB를 확인해 본 결과, github access token은 Account 콜렉션에 저장되어 있는 것을 알 수 있다. 따라서 로그인을 할 때 마다 이 값을 업데이트 해주고, GitHub API를 사용할 때 이 값을 불러오는 방식으로 구현했다.
100 Days Of Code 챌린지를 시작하고 일주일이 지났다.
그동안 새로 배워보고 싶다고 생각만 했던 Next.js, MongoDB를 사용해보면서 생각보다 일주일에 많은 양을 공부할 수 있다는 걸 깨달았다.
그리고 최대한 그 날의 느낀점을 요약해서 정리하려고 하는데, 내가 말로 설명을 잘 못한다는 걸 새삼 다시 느꼈다 ㅋㅋㅋ 원래 남한테 설명을 못하면 제대로 이해한게 아니라는 말이 있다. 앞으로는 공부한 걸 일목요연하게 정리하는 능력도 같이 길러야겠다.
또한 5일 연속으로 너무 달리다보니 집중이 안되서 중간에 하루를 쉬었다. 중간중간 본인이 조절하면서 번아웃이 오지 않도록 하는게 중요한 것 같다. 다음주차에는 지금하는 이 프로젝트를 마무리 지을 예정이다.