콜백 URL 단문서비스 활용방법 3가지
페이지 정보
작성자 Makayla 작성일25-03-25 02:38 조회1회 댓글0건관련링크
본문
1차 콜백URL단문서비스 백신 맞은날. (아직까진 아무렇지 않고 팔만 뻐근하다.)Node.js 교과서9장 익스프레스로 SNS 서비스 만들기SNS 중에서 140자의 단문메세지를 보내고사람들이 메세지의 내용을 공유할 수 있는 서비스를 노드로 만들기프런트엔드쪽 코드가 많이 들어가지만 노드와 익스프레스 코드위주로 집중폴더들이 자동생성npx 명령어로 전역설치 (-g) 를 피하기 위해서nodebird 폴더 내부 구조 완성위 구조는 고정된 구조는 아니라 바꿔도되지만 서비스가 성장하고 규모가 커질수록 폴더 구조도 복잡해지므로각각의 서비스에 맞는 구조를 적용해야함.npm i express cookie-parser express-session morgan multer dotenv nunjucksnpm i -D nodemonapp.js (1)app.js (2)라우터로는 현재 pageRouter만 있지만추후에 더 추가함,라우터 이후에는 404응답 미들웨어와 에러처리 미들웨어가 있음.마지막으로 앱을 8001번 포트에 연결..env하드코딩된 비밀번호가 유일하게 남아있는 파일이 있음.시퀄라이즈 설정을 담아둔 config.json이며,JSON파일이라 process.env를 사용할 수 없음.폴더안 파일들 추가routes/page.js위 page코드보면 GET /profile, GET /join, GET / 까지 총 세개의 페이지로 구성.router.use로 라우터용 미들웨어를 만들어템플릿엔진에서 사용할 user, followingCount, followerCount, followerIdList 변수를 res.locals로 설정.지금은 각각 null, 0, 0, [] 이지만나중에 값을 넣을 예정res.locals 로 값을 설정하는 이유는user, follwingCount, followerCount, followerList 변수를 모든 템플릿엔진에서공통으로 사용하기 때문render메서드 안의 twits도 지금은 빈 배열이지만 나중에 값을 넣을 예정view/layout.html (1)view/layout.html (2) ; ; window.onload =() =>{ if (new URL(location.href).searchParams.get(loginError)) { alert(new URL(location.href).searchParams.get(loginError)); } }; ;위 layout.html 에서 중요한 if문만 따로 기재.렌더링 할 때user가 존재하면 사용자 정보와 팔로잉, 팔로워 수를 보여주고,존재하지 않으면 로그인 메뉴를 보여줌.views/main.html (1)views/main.html (2)views/main.html (3)views/main.html (4)main.html 에서는user변수가 존재할 때 게시글 업로드 폼을 보여줌for문도 추가되었음.렌더링 시 twits배열안의 요소들을 읽어서 게시글로 만듦.지금은 빈 배열이지만 나중에 twits에 게시글 데이터를 넣으면 됨.if not followerIdList.includes(twit.User.id) and twit.User.id !==user.id 는나의 팔로워 아이디 목록에 게시글 작성자의 아이디가 없으면팔로우 버튼을 보여주기 위한 구문또한 게시글 작성자가 나인 경우 나를 팔로우 할 수는 없게 함.if not과 and를 써서 여러가지 조건들을 조합. 넌적스 문법 >if (userId !==myId.value) {views/profile.html위 profile.html 은 사용자의 팔로워와 사용자가 팔로잉 중인 목록을 보여줌.위 join.html 은 회원가입하는 폼을 보여줌.error.html 은 서버에 에러가 발생했을때에러 내역을 보여줌.에러는 콘솔로 봐도 되지만 브라우저 화면으로 보면 좀 더 편리하므로 위처럼 함.단, 배포 시에는 에러내용을 보여주지 않는게 보안상 좋음마지막으로 아래는 CSSpublic/main.css (1)public/main.css (2)public/main.css (3)public/main.css (4)public/main.css (5)public/main.css (6)npm start 입력시위와같이 책처럼 했지만 에러가 뜨는 모습..express-session 이 제대로 설치되지 않은것 같아 재설치현재 package.json오류: 세션에 비밀 옵션이 필요합니다. ??.... 안없어진다 ㅠ위 .env 파일에 COOKIE_SECRET 에 오타로 위처럼 떳지만 수정했더니(역시 지겨운 오타때매 ㅠㅠ_)다행히 이번엔 빠른시간내에 발견해서.. 시간을 많이 안뺏김아래와 같이 정상적으로 보인다.이메일과 비밀번호를 입력후 회원가입을 누르면 아래 페이지처럼 화면이 콜백URL단문서비스 달라진다.이메일, 닉네임, 비밀번호 창이 추가로 나오게 되고 회원가입 버튼이 아래에 생긴다.아무것도 입력하지 않은 상태로 카카오톡을 누르면 미연동 고객님이라고 나온다..아래는 이제 데이터 베이스 셋팅.MySQL과 시퀄라이즈로 데이터베이스 설정.로그인 기능이 있으므로 사용자 테이블이 필요하고,게시글을 저장할 게시글 테이블도 필요.해시태그를 사용하므로, 해시태그 테이블도 만들어야함.팔로잉 기능도 있음models/user.js (1)models/user.js (2)사용자 정보를 저장하는 모델이메일, 닉네임, 비밀번호를 저장하고,SNS 로그인을 했을 경우에는 provider와 snsId 를 저장.provider가 local이면 로컬 로그인을 한 것,kakao면 카카오 로그인기본적으로 로컬 로그인이라 가정해서 defaultValue를 local로 설정.>>테이블 옵션으로도 timestamps와 paranoid가 true로 주어졌으므로createAt, updateAt, deleteAt 컬럼도 생성.models/post.js게시글 모델은 게시글 내용과 이미지 경로를 저장.게시글 등록자의 아이디를 담은 컬럼은 나중에 관계를 설정할 때 시퀄라이즈가 알아서 생성.models/hashtag.js해시태그 모델은 태그 이름을 저장.해시태그 모델을 따로 두는 것은 나중에 태그로 검색하기 위해서이제 생성한 모델들을 시퀄라이즈에 등록.models/index.js에는 시퀄라이즈가 자동으로 생성한 코드들이 들어있는데기존파일 내용 지우고 아래처럼 수정.models/index.js _ 수정본각각의 모델들을 시퀄라이즈 객체에 연결.아래는 각 모델 간의 관계를 associate 함수 안에 정의한 것.models/user.js 해당 부분을 아래처럼 수정.models/user.js _수정본User모델과 Post 모델은 1(User):N(Post) 관계에 있으므로hasMany 로 연결되어 있음.user.getPosts, user.addPosts 같은 관계 메서드들이 생성됨.같은모델끼리도 N:M 관계를 가질수 있음.팔로잉 기능이 대표적인 N:M관계사용자 한명이 팔로워를 여러 명 가질 수도 있고, 한 사람이 여러명을 팔로잉 할 수도 있음.User 모델과 User모델 간에 N:M관계가 있는 것.같은 테이블 간 N:M 관계에서는 모델이름과 컬럼이름을 따로 정해야함.모델이름이 UserUser 일수 는 없으니까through 옵션을 사용해 생성할 모델이름을 Follow로 정함.Follow 모델에서 사용자 아이디를 저장하는 컬럼이름이 둘다 UserId명누가 팔로워이고 누가 팔로잉 중인지 구분되지 않으므로따로 설정해야함.foreignKey 옵션에 각각 followerId, followingId를 넣어줘서 두 사용자 아이디를 구별. 같은 테이블 간의 N:M관계에서는as옵션도 넣어야 함.둘가 User모델이라 구분되지 않기 때문.주의사항은 as는 foreignKey와 반대되는 모델을 가르킨다는 것.foreignKey가 followerId(팔로워 아이디) 이면 as는 Followings(팔로잉)이고,foreignKey가 followingId(팔로잉 아이디)dlaus as는 Followers(팔로워)여야 한다.팔로워를 찾으려면 먼저 팔로잉 하는 사람의 아이디를 찾아야하는 것이라 보면 됨.as에 특정한 이름을 지정했으니 user.getFollowers, user.getFollowings 같은 관계 메서드를 사용가능.include 시에도 ad에 같은 값을 넣으면 관계 쿼리가 작동.Post 모델도 아래와 같이 수정.User 모델과 Post 모델은 1(User) : N(Post) 관계이므로belongsTo로 연결되어 있음.시퀄라이즈는 Post 모델에 User모델의 id를 가르키는 UserId 컬럼을 추가.어디에 컬럼이 추가되는 것인지 관계를 생각해보면 쉬움.사용자가 한명이고 그에 속한 게시글이 여러개이므로각각의 게시글에 게시글의 주인이 누구인지를 넣어야함.belongsTo는 게시글에 붙음.post.getUser, post.addUser와 같은 관계 메서드가 생성.Post모델과 Hashtag모델은 N:M 관계.N:M관계이므로 PostHashtag라는 중간 모델이 생기고,각각 postId 와 hashtagId라는 foreignKey도 추가.as는 따로 지정하지 않아서post.getHashtags, post.addHashtags, hashtags.getPosts같은 기본 이름의 관계 메서드들이 생성.hashtag 모델도 아래와 같이 수정.models/hashtag.jsHashtag 모델은 Post모델과 N:M관계이므로 콜백URL단문서비스 관계를 설정.NodeBird의 모델은 총 5개.즉, 직접생성한 User / Hashtag / Post와 시퀄라이즈가 관계를 파악하여생성한 PostHashtag, Follow 까지.자동으로 생성된 모델도 다음같이 접근 가능다음모델을 통해 쿼리 호출이나 관계 메서드 사용도 가능.db.sequelize.models.PostHashtagdb.sequelize.models.Follow이제 생성한 모델을 데이터 베이스 및 서버에 연결아직 데이터 베이스를 안만들어서데이터 베이스 부터 만듦.데이터 베이스의 이름은 nodebird.config.json 파일을 위처럼 MySQL비밀번호와 데이터 베이스를 수정.터미널에 npx sequelize db:create 입력.app.js _ 수정본위는 데이터베이스를 생성했으니 모델을 서버와 연결한 것.서버쪽 세팅 완료.시퀄라이즈는 테이블 생성 쿼리문에 IF NOT EXISTS 를 넣어주므로 테이블이 없을때 테이블을 자동으로 생성.위처럼 뜨면 데이터베이스 세팅 완료사용자 정보를 저장할 수 있게 된것.아래는 이제 로그인 구현회원가입과 로그인을 직접 구현할 수도 있지만, (팀플이나 기존에 했던방식 등..)세션과 쿠키처리 등 복잡한 작업이 많으므로 검증된 모듈을 사용하는것이 좋다.바로 Passport 를 사용하는 것.위 모듈은 이름처럼 우리의 서비스를 사용할 수 있게 해주는 여권같은 역할.서비스를 로그인할때 아이디와 비밀번호를 직접 입력하지 않아도구글, 페이스북, 카카오톡, 네이버 등 같은 기존의 SNS 서비스 계정으로 로그인하기도 함.Passport를 사용해서 해결가능.자체 회원가입 및 로그인 방법뿐만 아니라 한국에서 많이 사용하는 SNS 인 카카오톡을 이용해로그인하는 방법 2가지로 구현!npm i passport passport-local passport-kakao bcrypt위처럼 Passport 모듈을 설치하고아래처럼 미리 app.js와 연결 app.js _수정본 일부app.js _수정본 일부require('./passport')는 require('./passport/index.js')와 같음.폴더 내의 index.js파일은 require시 이름을 생략 가능passport.initialize 미들웨어는 요청 (req객체)에 passport설정을 심고,passport.session미들웨어는 req.session 객체에 passport정보를 저장.req.session객체는 express-session 에서 생성하는 것이므로 passport미들웨어는 express-session미들웨어보다 뒤에 연결해야함.passport/index.js이 부분이 Passport를 이해하는 핵심.serializeUser는 로그인 시 실행,req.session(세션)객체에 어떤 데이터를 저장할지 정하는 메서드.매개변수로 user를 받고나서 done함수에 두번째 인수로 user.id를 넘기고 있음.매개변수 user는 사용자 정보가 들어있다.done함수의 첫번째 인수는 에러발생시 사용하는 것.두번째 인수에는 저장하고 싶은 데이터를 넣음.로그인시 사용자 데이터를 세션에 저장하는데,세션에 사용자 정보를 모두 저장하면 세션의 용량이 커지고 데이터 일관성에 문제가 발생,그래서 사용자의 아이디만 저장하라고 명령serializeUser 가 로그인시에만 실행된다면,deserializeUser는 매 요청 시 실행.passport.session 미들웨어가 이 메서드를 호출serializeUser의 두번째 인수로 넣었던 데이터가deserializeUser의 매개변수가 됨. 여기서는 사용자의 아이디.serializeUser에서 세션에 저장했던 아이디를 받아 데이터 베이스에서 사용자 정보를 조회.조회한 정보를 req.user에 저장하므로 앞으로 req.user를 통해 로그인한 사용자의 정보를 가져올 수 있음.즉, serializeUser 는 사용자 정보 객체를 세션에 아이디로 저장,deserializeUser는 세션에 저장한 아이디를 통해 사용자 정보 객체를 불러오는 것.세션에 불필요한 데이터를 담아주지 않기 위한 과정. ;1. 라우터를 통해 로그인 요청이 들어옴.3. 로그인 전략 수행4. 로그인 성공시 사용자 정보 객체와 함께 req.login호출5. req.login메서드가 passport.serializeUser호출6.req.session에 사용자 아이디만 저장7. 로그인 완료;1. 요청이 들어옴2. 라우터에 요청이 도달하기 전에 3. req.session에 저장된 아이디로 콜백URL단문서비스 데이터베이스에서 사용자 조회4. 조회된 사용자 정보를 req.user에 저장.5. 라우터에서 req.user객체 사용 가능passport/index.js 의 localStrategy와 kakaoStrategy파일은 각각 로그인과 카카오로그인 전략에 대한 파일Passport는 로그인 시의 동작을 전략이라는 용어로 표현로그인 과정을 어떻게 처리할지 설명하는 파일.로컬 로그인이란다른 SNS 서비스를 통해 로그인하지 않고 자체적으로 회원가입 후 로그인하는 것을 의미즉. 아이디/비밀번호 또는 이메일/비밀번호를 통해 로그인하는 것.Passport에서 이를 구현하려면 passport-local 모듈이 필요. (위에서 설치)로그인에만 해당하는 전략이므로 회원가입은 따로 만들어야함.회원가입, 로그인, 로그아웃 라우터를 먼저 만들고이런 라우터에는 접근조건이있음.로그인한 사용자는 회원가입과 로그인 라우터에 접근하면 안됨. (이미 로그인한 상태니.)로그인하지 않은 사용자는 로그아웃 라우터에 접근하면 안됨.따라서 라우터에 권한 접근을 제어하는 미들웨어 필요미들웨어를 만들어보며 Passport가 req객체에 추가해주는 req.isAuthenticated메서드를 사용.routes/middlewares.jsPassport 는 req객체에 isAuthenticated 메서드를 추가.로그인 중이면 req.isAuthenticated()가 true고, 그렇지 않으면 false따라서 로그인 여부를 메서드로 파악가능라우터들 중 로그아웃 라우터나 이미지 업로드 라우터 등로그인한 사람만 접근할 수 있게 하고회원가입라투어나 로그인 라우터는 로그인하지 않은 사람만 접근할 수 있게 해야함.이럴때 라우터에 로그인 여부를 검사하는 미들웨어를 넣어 걸러냄.isLoggedIn과 isNotLoggedIn 미들웨어를 만들었고 이 미들웨어들이 page라우터에 아래처럼 적용routes/page.js _수정본자신의 프로필은 로그인을 해야 볼 수 있으므로isLoggedIn 미들웨어를 사용.req.isAuthenticated()가 true여야 next가 호출되어res.render가 있는 미들웨어로 넘어갈 수 있음.false라면 로그인 창이 있는 메인 페이지로 리다이렉트 됨.회원가입 페이지는 로그인을 하지 않은 사람에게만 보여야 함.따라서 isNotLoggedIn 미들웨어로 req.isAuthenticated()가 false일때만 next를 호출하도록 했음.로그인 여부로만 미들웨어를 만들 수 있는 것이 아니라팔로잉 여부, 관리자 여부 등의 미들웨어도 만들수 있음.다양하게 활용가능res.locals.user 속성에 req.user를 넣은것.넌적스에서 user객체를 통해 사용자 정보에 접근할 수 있게 됨.routes/auth.js (1)routes/auth.js (2)routes/auth.js (3)routes/auth.js (4)추후 app.js 와 연결할때,/auth 접두사를 붙일 것이므로 라우터의 주소는 각각/auth/join, /auth/login, /auth/logout 이 됨.routes/auth.js (2) : 회원가입 라우터기존에 같은 이메일로 가입한 사용자가 있는지 조회한 뒤있다면 회원가입 페이지로 되돌려 보냄.단, 주소 뒤에 에러를 쿼리스트링으로 표시같은 이메일로 가입한 사용자가 없다면 비밀번호를 암호화,사용자정보를 생성.회원가입시 비밀번호는 암호화해서 저장해야함.bcrypt모듈을 사용 (crypto모듈의 pbkdf2 메서드를 사용해서 암호화도 가능)숫자가 커질수록 비밀번호를 알아내기 어려워지지만 암호화 시간도 오래걸림.12이상 추천 31까지 허용.프로밈스를 지원하는 함수이므로 await를 사용.routes/auth.js (3) : 로그인 라우터미들웨어인데 라우터 미들웨어 안에 들어있음.미들웨어에 사용자 정의 가능을 추가하고는내부 미들웨어에 (req, res, next)를 인수로 제공해서 호출전략이 성공하거나 실패하면authenticate 메서드의 콜백함수가 실행콜백함수의 첫번째 매개변수값이 있다면 실패한것.두번째 매개변수 값이 있다면 성공. req.login 메서드를 호출Passport 는 req객체에 login과 logout 메서드를 추가req.login은 passport, serializeUser를 호출.req.login 에 제공하는 user객체가 serializeUser로 넘어가게 됨.routes/auth.js (4) : 로그아웃 라우터req.user 객체를 제거하고, req.session, destroy는 req.session 객체의 내용을 제거.세션 정보를 지운 후 메인페이지로 되돌아 감.로그인이 콜백URL단문서비스 해제되어있을것.passport/localStrategy.js위는 로그인 전략을 구현한것, passport-local 모듈에서 Strategy생성자를 불러와 그안에 전략을 구현하면 됨.module.exports =() =>{ passport.use( new LocalStrategy( { usernameField: email, passwordField: password, },위 LocalStrategy생성자의 첫번째 인수로 주어진 객체는 전략에 관한 설정을 하는 곳.usernameField와 passwordField에는 일치하는 로그인 라우터의 req.body속성명을 적으면 됨.req.body.email에 이메일주소가, req.body.password 에 비밀번호가 담겨들어오므로 email 과 password를 각각 넣음.아래 실제전략을 수행하는 async함수.localStrategy생성자의 두번째 인수로 들어감.첫번째 인수에서 넣어준 email과 password는 각각 async함수의 첫번째와 두번째 매개변수가 됨.전략내용은먼저 사용자 데이터베이스에서 일치하는 이메일이 있는지 찾은후,있다면 bcrypt의 compare함수로 비밀번호를 비교,비밀번호까지 일치한다면 done함수의 두번째 인수로 사용자의 정보를 넣어 보냄.두번째 인수를 사용하지 않는 경우는 로그인에 실패했을때 뿐.done 함수의 첫번째 인수를 사용하는 경우는 서버쪽에서 에러가 발생햇을때이고,세번째 인수를 사용하는 경우는 로그인 처리과정에서 비밀번호가 일치하지 않거나존재하지 않는 회원일 때와 같은 사용자 정의 에러가 발생했을때.로그인에 성공햇다면 메인페이지로 리다이렉트되면서 로그인 폼 대신 회원정보가 뜰 것.아직 auth 라우터를 연결하지 않았으므로 코드가 작동하지 않음.카카오 로그인까지 구현한 후 연결.카카오 로그인이란 ? 로그인 인증과정을 카카오에 맡기는 것.사용자는 번거롭게 새로운 사이트에 회원가입을 하지 않아도되므로 좋고,서비스 제공자는 로그인 과정을 검증된 SNS 에 안심하고 맡길 수 있어 좋음.;회원가입 절차가 따로 없다.처음 로그인할때는 회원가입 처리를 해야하고두번째 로그인부터는 로그인처리를 해야함.따라서 SNS 로그인 전략은 로컬로그인 전략보다는 다소 복잡.passport/kakaoStrategy.jspassport-kakao 모듈부터 Strategy생성자를 불러와 전략을 구현처음에 로컬 로그인과 마찬가지로 카카오 로그인에 대한 설정,clientID는 카카오에서 발급해주는 아이디노출되지 않아야 하므로 process.env.KAKAO_ID로 설정.나중에 아이디를 발급받아 .env파일에 넣을 것.callbackURL은 카카오로부터 인증 결과를 받을 라우터 주소.아래 라우터를 작성할 대 이 주소를 사용.먼저 기존 카카오를 통해 회원가입한 사용자가 있는지 조회있다면 이미 회원가입되어있는 경우이므로 사용자정보와 함게 done함수를 호출하고 전략을 종료카카오를 통해 회원가입한 사용자가 없다면 회원가입을 진행카카오에서는 인증후 callbackURL에 적힌 주소로 accessToken, refrechToken 과 profile을 보냄.profile에는 사용자정보들이 들어있음.카카오에서 보내주는 것이므로 데이터는 console.log메서드로 확인해보는게 좋음profile객체에서 원하는 정보를 꺼내와 회원가입을 하면 됨.사용자를 생성한 뒤 done함수를 호출아래는 카카오 로그인 라우터로그아웃라우터 아래에 추가회원가입을 따로 코딩할 필요없고, 카카오 로그인 전략이 대부분 로직을 처리라우터가 상대적으로 간단.routes/auth.js _수정본GET /auth/kakao 로 접근하면 카카오 로그인 과정이 시작. layout.html의 카카오톡버튼에 /auth/kakao 링크가 붙어있음GET /auth/kakao에서 로그인 전략을 수행하는데처음에는 카카오 로그인 창으로 리다이렉트그 창에서 로그인 후 성공여부 결과를 GET /auth/kakao/callback 으로 받음.이 라우터에서는 카카오 로그인 전략을 다시 수행.카카오 로그인은 로그인 성공시 내부적으로 req.login 을 호출.우리가 직접 호출할 필요가 없음.콜백 함수 대신 로그인 실패했을때 어디로 이동할지를 failureRedirect 속성에 적고,성공시에도 어디로 이동할지를 다음 미들웨어에 적음.아래는 추가한 auth라우터를 app.js에 연결app.js 수정부분 (1)app.js 수정부분 (2)아래는 콜백URL단문서비스 kakaoStrategy.js 에서 사용하는 clientID를 발급받는 것.카카오 로그인을 위해서는카카오 개발자 계정과 카카오 로그인용 애플리케이션 등록이 필요.카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다. 위로 접속해서 카카오 회원가입 또는 로그인애플리케이션 추가하기 버튼 클릭.카카오용 NodeBird 앱을 만듦앱아이콘은 등록안해도되고 앱이름과 회사명 등록하면됨.팀플때 사용한 케이크 사진이 있어 임의로 넣어둠앱 생성후 화면REST API 키를 복사하여 .env 파일에 넣음키는 다다름.위 입력후 저장을 누르면 이렇게 나온다.제품설정 >카카오로그인 메뉴에서 활성화 설정활성화 설정상태를 ON 으로 변경auth/kakao/callback부분은 kakaoStrategy.js의 callbackURL과 일치해야함.카카오계정 이메일 설정 클릭선택동의로 바뀌어있다.NodeBird서비스에서 카카오톡 버튼을 눌러 GET /auth/kakao라우터로 요청을 보내면 카카오 인증이 시작됨.이미 카카오에 로그인 되어 있다면 로그인 화면이 뜨지 않는다.로컬 로그인과 카카오 로그인 모두 해보면 Passport 인증과정을 다시 되짚어볼수 있음.로그인한 계정은 계속 사용됨.카카오로 로그인하려고하면 위처럼 뜬다.8002 번 포트로 변경시 카카오 RedirectURL도 변경해야한다. 로그인페이지에 이름과 정보를 아무것도 안쳤고 재방문 경우관리자 설정이슈 페이지 / 관리자로 등록된 경우 뜨게 된다.에러페이지 > 8001 포트로 등록했는데 8002로 변경해서 그런경우 발생카카오 API를 활용하여 다양한 어플리케이션을 개발해보세요. 카카오 로그인, 메시지 보내기, 친구 API, 인공지능 API 등을 제공합니다.회원가입하고 로그인후 화면카카오 로그인 외에 구글, 페이스북, 네이버, 트위터 로그인도 가능 npm 에서 찾아 사용하면 됨.로그아웃 버튼을 누르면 NodeBird 서비스에서 로그아웃됨.다만, 카카오에서 로그아웃되는 것은 아니므로 다음번에 카카오를 통해NodeBird에 로그인할때는 카카오 로그인 없이 바로 서비스에 로그인됨.카카오에서도 로그아웃하고 싶다면 공식문서를 참조지금 보니 생성된 폴더 파일리스트가 장난아니다..드뎌 막바지로multer 패키지로 이미지 업로드SNS 서비스인 만큼 이미지 업로드도 중요multer 모듈을 사용해 멀티파트 형식의 이미지를 업로드npm i multer 설치이미지를 어떻게 저장할 것인지는 서비스의 특성에 따라 달라짐.NodeBird 서비스는 input 태그를 통해 이미지를 선택할 때 바로 업로드를 진행하고,업로드된 사진 주소를 다시 클라이언트에 알릴것.게시글을 저장할때는 데이터베이스에 직접 이미지 데이터를 넣는 대신이미지 경로만 저장, 이미지는 서버 디스크에 저장.routes/post.js (1)routes/post.js (2)routes/post.js (3)multer 부분은 6장 내용과 코드가 거의 유사POST /post/img 라우터와 POST /post 라우터를 만듦.app.use('/post')를 할것이므로 앞에 /post경로가 붙음.POST /post/img 라우터에서는 이미지 하나를 업로드 받은 뒤이미지의 저장 경로를 클라이언트로 응답.static미들웨어가 /img 경로의 정적 파일을 제공하므로클라이언트에서 업로드한 이미지에 접근할 수 있음.POST /post 라우터는 게시글 업로드를 처리하는 라우터이전 라우터에서 이미지를 업로드 했다면 이미지 주소도 req.body.url로 전송비록 데이터 형식이 multipart이지만 이미지 데이터가 들어있지 않으므로 none 메서드를 사용이미지 주소가 온것일 뿐 이미지 데이터 자체가 오지는 않음이미지는 이미 POST /post/img 라우터에서 저장.게시글은 데이터베이스에 저장한 후, 게시글 내용에서 해시태그를 정규표현식(/#[^\s#]+/g)으로 추출해냄.추출한 해시태그는 데이터베이스에 저장,먼저 slice(1).toLowerCase() 를 사용해 해시태그에서 콜백URL단문서비스 #을떼고 소문자로 바꿈저장할때는 findOrCreate 메서드를 사용함.이 시퀄라이즈 메서드는 데이터베이스에서 해시태그가 존재하면 가져오고존재하지 않으면 생성한 후 가져옴결괏값으로 [모델, 생성여부]를 반환하므로 result.map(r => r[0])으로 모델만 추출.마지막으로 해시태그 모델들을 post.addHashtags 메서드로 게시글과 연결.;현재 multer 패키지는 이미지를 서버디스크에 저장디스크에 저장하면 간단하기는 하지만, 서버에 문제가 생겼을때 이미지가 제공되지 않거나 손상될 수 있음.따라서 AWS 나 S3나 클라우드 스토리지 같은 정적 파일 제공 서비스를 사용하여이미지를 따로 저장하고 제공하는 것이 좋음.이러한 서비스를 사용하고 싶다면 multer-s3나 multer-google-storage 같은 패키지를 찾아보면 됨.이제 게시글 작성 기능이 추가되서 메인페이지 로딩시메인페이지와 게시글을 함께 로딩.routes/page.js _수정본 (1)routes/page.js _수정본 (2)먼저 데이터베이스에서 게시글을 조회한 뒤 결과를 twits에 넣어 렌더링 함.조회할 때 게시글 작성자의 아이디와 닉네임을 JOIN해서 제공게시글의 순서는 최신순으로 정렬아래는 팔로잉 기능과 해시태그 검색 기능만 추가하면 됨.다른 사용자를 팔로우 하는 기능을 만들기 route/user.jsPOST /user/:id/follow 라우터:id 부분이 req.params.id 가 됨.먼저 팔로우할 사용자를 데이터베이스에서 조회한 후,시퀄라이즈에서 추가한 addFollowing 메서드로 현재 로그인한 사용자와의 관계를 지정팔로잉 관계가 생겼으므로 req.user에도 팔로워와 팔로잉 목록을 저장.앞으로 사용자 정보를 불러올때는 팔로워와 팔로잉 목록도 같이 불러오게 됨.req.user 를 바꾸려면 deserializeUser를 조작해야함.세션에 저장된 아이디로 사용자정보를 조회할 때팔로잉 목록과 팔로워 목록도 같이 조회.include에서 계속 attributes를 지정하고 있는데,이는 실수로 비밀번호를 조회하는 것을 방지하기 위해서;라우터가 실행되기 전에 deserializeUser 가 먼저 실행됨.따라서 모든 요청이 들어올때마다 매번 사용자 정보를 조회하게 됨.서비스의 규모가 커질수록 더 많은 요청이 들어오게 되고,그로인해 데이터베이스에도 더 큰 부담이 주어짐.따라서사용자 정보가 빈번하게 바뀌는 것이 아니라면 캐싱을 해두는 것이 좋음.다만, 캐싱이 유지되는 동안팔로워와 팔로잉 정보가 갱신되지 않는 단점이 있다.캐싱시간은 서비스 정책에따라 조절해야함.실제서비스에서는 메모리에 캐싱하기보다는 레디스 같은 데이터베이스에 사용자정보를 캐싱.아래는 팔로잉/팔로워 숫자와 팔로우 버튼을 표시하기 위해 routes/page.js를 수정.책대로하니 정의되지 않았다는 ... 모양이 나온다.로그인한 경우에는req.user 가 존재하므로 팔로잉/팔로워 수와 팔로워 아이디 리스트를 넣음팔로워 아이디 리스트를 넣는 이유는팔로워 아이디 리스트에 게시글 작성자의 아이디가 존재하지 않으면 팔로우 버튼을 보여주기 위해서routes/page.js (1) _수정본routes/page.js (2) _수정본routes/page.js (3) _수정본해시태그로 조회하는 GET /hashtag 라우터.쿼리스트링으로 해시태그 이름을 받고 해시태그 값이 없는 경우 메인페이지로 돌려보냄.데이터베이스에서 해당 해시태그를 검색한 후,해시태그가 있다면 시퀄라이즈에서 제공하는 getPosts메서드로 모든 게시글을 가져옴.가져올때는 작성자 정보를 합침.조회 후 메인페이지를 렌더링하면서 전체 게시글 대신 조회된 게시글만 twits에 넣어 렌더링.마지막으로 routes/post.js 와 routes/user.js 를 app.js에 연결업로드한 이미지를 제공할 라우터 (/img)도 express.static 미들웨어로 uploads폴더와 연결express.static을 여러번 쓸 수 있다는 사실app.js _ 수정본 (1)app.js _ 수정본 (2)완성본 결과물팔로우하기 버튼을 누르면 아래처럼 팔로잉한 숫자가 카운트 된다. 이번 9장에서 느낀것.에러나는 콜백URL단문서비스 이유의 90프로는 오탈자로오타없는지 파악하는게 젤 중요하다.근데 스스로해보기 아래 내역은 .. 일단 보류10장부터 먼저해보고 해야할것 같다.. 아니면 10, 12, 13 과제를 전부 손도 못대고시간만 지나갈것같아서 우선 다음장 진도나가고 다시 수정하는걸로;1. 팔로잉 끊기( 시퀄라이즈의 destroy 메서드와 라우터 활용 )2. 프로필 정보 변경하기 ( 시퀄라이즈의 update 메서드와 라우터 활용 )3. 게시글 좋아요 누르기 및 좋아용 취소하기( 사용자 - 게시글 모델 간 N:M 관계 성립후 라우터 활용 )4. 게시글 삭제하기( 등록자와 현재 로그인한 사용자가 같을때, 시퀄라이즈의 destroy 메서드와 라우터 활용 )5. 매번 데이터베이스를 조회하지 않도록 deserializeUser 캐싱하기( 객체 선언 후 객체에 사용자 정보 저장, 객체안에 캐싱된 값이 있으면 조회 ) ;- 서버는 요청에 응답하는 것이 핵심 임무이므로요청을 수락하든 거절하든 상관없이 반드시 응답해야함.이때 한번만 응답해야 에러가 발생하지 않는다.- 개발시 서버를 매번 수동으로 재시작 하지 않으려면 nodemon을 사용하는 것이 좋음.- dotenv 패키지와 .env 파일로 유출되면 안되는 비밀키 관리- 라우터는 routes 폴더에, 데이터베이스는 models 폴더에, html파일은 views폴더에구분하여 저장하면 프로젝트 규모가 커져도 관리하기 쉬움.- 데이터 베이스를 구성하기 전에 데이터 간 1:1 , 1: N , N:M 관계를 잘 파악 !- routes/middlewares.js 처럼 라우터 내에 미들웨어를 사용할 수 있다는 것을 기억.- Passport 의 인증과정을 기억.특히, serializeUser와 deserializeUser가 언제 호출되는지 파악하고 있어야 함.- 프런트엔드 form태그의 인코딩 방식이 multipart일 때는 multer 같은 multipart 처리용 패키지를 사용하는 것이 좋음.
댓글목록
등록된 댓글이 없습니다.