Tech Blog of Pinomaker
전 게시글 확인!
 

[Node JS] typescript + sequelize + passport로 유저 API 개발 - Local User 생성

전 게시글을 확인하고 읽어주시기 바랍니다:) [Node JS] typescript + sequelize + passport로 유저 API 개발 - Sequelize 셋팅 해당 포스트는 Typescript가 셋팅 되어있어야 합니다. [Node JS] Node.js를 Typescr..

pinomaker.com

 

passport는 Node에서 로그인을 처리하기 위한 모듈이다. 

 

간단하게 생각해서 여권이라고 생각하면 되는 데, 서비스를 개발하면 로컬 유저만 있는 경우도 있지만, 구글과 카카오 등 oauth를 이용한 다양한 종류의 유저를 처리해야할 때가 있는 데 이 때 passport를 사용하면 편리하다.

 

로그인 할 때 나라별 여권이 있는 것처럼, 로컬인지 카카오인지 등의 유저 종류에 따라서 로그인 로직을 쉽게 나눌 수 있는 장점이 있다.

 

1. 1. 필요한 모듈 설치

2.  

먼저 passport 개발을 위해 필요한 모듈을 아래와 같이 설치하자.

  • passport, @types/passport : passport 설정을 위한 모듈
  • passport-local, @types/passport-local : 로컬 로그인을 위한 passport 모듈
  • jsonwebtoken, @types/jsonwebtoken : jwt 관련 모듈
<bash />
npm install passport passport-local jsonwebtoken npm install --save-dev @types/passport @types/passport-local @types/jsonwebtoken

 

3. 2.  passport 셋팅

passport 셋팅을 해주기 위하여 먼저 src/index.ts에서 아래와 같이 passport를 위한 코드를 추가해준다!

 

passport 설정을 담은 PassportConfig를 가져와 실행 시키고, passport 사용을 위한 passport.initalize를 이용하여 설정한다.

 
<typescript />
// src/index.ts import express from 'express' import passport from 'passport' import sequelize from './models' const app = express() // passport 파일 가져오기 const PassportCofig = require('./utils/passport') // passport 실행 PassportCofig() app.use(express.json()) app.use(express.urlencoded({ extended: false })) // passport 설정 app.use(passport.initialize()) app.use('/api', require('./api')) const port: number = 3000 app.listen(port, async () => { console.log(`SERVER ON! PORT : ${port}`) await sequelize .authenticate() .then(async () => { console.log('connection success') }) .catch((e) => { console.log(e) }) })

 

4. 3. passport 설정 파일 작성

src에 utils 폴더를 만들고 passport 폴더와 그 안에 index.ts를 생성한다.

해당 파일에는 passport 종류에 따른 분기처리를 하는 코드라고 생각하면 된다.

일단 passport-local, 로컬 로그인만 작성해준다.

<typescript />
// src/utils/passport/index.ts import passportLocal from 'passport-local' import passport from 'passport' import { User } from '../../models/domain/User' import * as bcrypt from 'bcrypt' // passport-local 설정 const LocalStrategy = passportLocal.Strategy module.exports = () => { // passport에서 "local"이면 해당 로직으로 들어옴. passport.use( new LocalStrategy( { usernameField: 'email', passwordField: 'password', }, // Local Login 처리 로직 async (email: any, password: any, done: any) => { try { // sequelize를 이용해 email를 검색해 유저를 조회한다. const findUser = await User.findOne({ where: { email: email } }) // 유저가 없으면 없는 회원이라는 실패 로직 처리 if (!findUser) done(null, false, { message: '가입되지 않은 회원 입니다.' }) else { // 유저가 있으면 비밀번호를 암호화 해제를 해본다. const result = await bcrypt.compare(password, findUser.password) result ? done(null, findUser) // 비밀번호 일치하면 로그인 성공 : done(null, false, { message: '비밀번호가 일치 하지 않음' }) // 일치 안 하면 실패 } } catch (err) { console.error(err) // 에러 로직 done(err) } }, ), ) }

 

5. 4. Local Login 작성

이제 user.service에 아래의 코드를 작성하자.

localLogin 함수는 passport-local를 호출하는 코드라고 생각하면 된다.

로그인이 성공하면, 유저의 idx를 이용하여 jwt를 생성하고 cookie에 담아서 보낸다.

<typescript />
// src/api/user/user.service.ts import { Response, Request } from 'express' import { User } from '../../models/domain/User' import * as bcrypt from 'bcrypt' import { Provider } from '../../models/interface/User.interface' import passport from 'passport' import jwt from 'jsonwebtoken' exports.saveUser = async (req: Request, res: Response) => { try { const { email, password, name } = req.body const hash = await bcrypt.hash(password, 10) const saveUser = await User.create({ email, password: hash, name, provider: Provider.LOCAL, }) res.json({ result: true, user: saveUser }) } catch (err) { console.log(err) } } // Local Login exports.localLogin = async (req: Request, res: Response) => { // passport-local로 전송 passport.authenticate('local', { session: false }, (err, user) => { // passport-local 결과에서 Err가 있거나, 유저가 없을 때 if (err || !user) { return res.status(400).json({ message: 'Something is not right', user: user, }) } // 로그인 후 코드 작성 req.login(user, { session: false }, (err) => { // err 있을 때 처리 if (err) { console.log(err) res.send(err) } // jwt를 이용하여 token을 생성 const token = jwt.sign({ idx: user.idx }, '123') // cookie에 accessToken에 token을 담아서 저장 res.cookie('accessToken', token, { expires: new Date(Date.now() + 86400e3), sameSite: 'lax', }) // user 정보 리턴 return res.send({ user }) }) })(req, res) }

 

 

그리고 /src/api/user/index.ts에서 라우팅 처리까지 해주면 끝이다.

<typescript />
// src/api/user/index.ts const router = require('express').Router() const user = require('./user.service') router.post('/', user.saveUser) //Local Login 추가 router.post('/local', user.localLogin) module.exports = router export {}

 

Postman으로 API를 실행하면 쿠키도 잘 담겨오고 실행도 잘 되는 것을 볼 수 있다.

profile

Tech Blog of Pinomaker

@pinomaker

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!