Elice SW engineer - TIL day 35

Circlewee·2022년 5월 20일
0

Elice SW 2 TIL

목록 보기
30/31

1. JWT

  • Json Web Token
  • 인증을 위한 정보를 특별한 저장소를 이용하지 않고, 전자 서명을 이용하여 확인하는 방법
  • base64인코딩을 사용

1.1 인증방식

  1. 사용자 로그인
  2. 서버는 로그인된 유저 정보를 JWT로 생성하여 클라이언트에 전달
  3. 클라이언트는 전달받은 JWT를 이용하여 인증이 필요한 요청에 사용(header에 포함)

1.2 Why JWT?

  • session은 기본적으로 웹 브라우저의 통신 스펙이기 때문에 모바일 앱등 브라우저가 아닌 앱의 경우 이를 활용하기 부적합하다. JWT를 사용하면 어느 클라이언트에서나 동일한 방식의 사용자 인증을 구현할 수 있다.
  • 로그인 로직에서 JWT를 생성한 후 쿠키로 전달한다.
setUserToken = (res, user) => {
  const token = jwt.sign(user, secret);
  res.cookie('token', token);
}

router.post('/', passport(authenticate('local'), (req, res, next) => {
  setUserToken(res, req.user);
  res.redirect('/');
}
// using passport-jwt
const JwtStrategy = require('passport-jwt').Strategy;
const cookieExtractor = (req) => {
  const { token } = req.cookies;
  return token;
}

const opts = {
  secretOrKey: secret,
  jwtFromRequest: cookieExtractor,
}

module.exports = new JwtStrategy(opts, (user, done) => {
  done(null, user);
});

---
// passport.session()
passport.use(jwt);

1.4 JWT middleware

app.use((req, res, next) => {
  if (!req.cookies.token) {
    next();
    return;
  }
  return passport.authenticate('jwt')(req, res, next);
}

+ logout

res.cookie('token', null, {
  maxAge: 0
})

2. 비밀번호 찾기

  1. 임의의 문자열로 초기화
  2. 초기화된 문자열을 메일로 전달
  3. 초기화 후 첫 로그인 시 비밀번호 변경 요청

2.1 메일발송 기능

  1. SMTP 서버 이용
  2. 메일 발송 서비스 이용

2.2 Nodemailer + gmail

const nodemailer = require('nodemailer');

const transport = nodemailer
  .createTransport({
    service: 'Gmail',
    auth: {
      user: 'google account',
      pass: 'app password',
    },
  });
const message = {
  from: 'login account',
  to: 'mail address',
  subject: 'title',
  text: 'message'
};

transport.sendMail(message, (err, info) => {
  if(err) {
    console.error('err', err);
    return;
  }
  console.log('ok', info);
});
function generateRandomPassword() {
  return ...랜덤 비밀번호 알고리즘
}

router.post('/reset-password', asyncHandler(...) => {
  const { email } = req.body;
  const randomPassword = generateRandomPassword();
  await User.findOneAndUpdate({ email }, {
    password: getHash(randomPassword),
  });

  await sendEmail(email, '...', password);
  res.redirect('/');
}));

3. OAuth

  • 서비스 제공자가 다른 서비스에게 데이터를 제공하기 위해 서비스 사용자에게 제공하는 인증방식의 표준

3.1 Google OAuth w/ passport

const GoogleStrategy = require('passport-google-oauth20').Strategy;
const config = {
  cliendID: 'clientID',
  clientSecret: 'clientSecret',
  callbackURL: 'callbackUrl',
};

new GoogleStrategy(config, (accessToken, refreshToken, profile, done) => {
  const { email, name } = profile._json;
  ...
}
passport.use(google);
...
router.get('/google', passport.authenticate('google', {
  scope: ['profile', 'email']
}));

router.get('/google/callback', passport.authenticate('google', {
  failureRedirect: '/login'
}), (req, res, next) => {
  res.redirect('/');
});

4. 프로젝트 전 생각

한 8주동안 매일 TIL을 적으면서 느낀 것이 있다. 과연 매일 배운 것을 작성하는 것이 가지는 의미가 무엇인가?
1. 강의를 들으며 배운 것을 정리한다.
2. 기록을 남겨 나중에 헷갈리는 부분에서 참고한다.
이 정도일 것 같다. 다만 글을 계속 작성하면서 드는 생각이 수업을 듣고 뒤에 할일이 많을 때면 글을 적는 시간이 너무 길다고 느껴졌고 앞으로는 수업을 들으면서 궁금증이 생긴 부분을 자세히 파보거나 몰랐던 부분을 위주로 작성할 것 같다.

profile
공부할 게 너무 많아요

0개의 댓글

관련 채용 정보