JWT/OAuth

박태욱·2022년 1월 18일
0
post-thumbnail

기존의 세션 방식은 ID를 HTTP 클라이언트로 바로 보내기 때문에 보안이 매우 약하고 로그인을 유지할 경우, 필요공간이 많아진다. 그래서 Token, JWT, OAuth 방식을 사용한다.

  1. Token(JWT)
    클라이언트에 사용자가 로그인하면 DB에서 사용자를 확인한 후 서버에서 Access Token(JWT) 발급한다. 클라이언트는 Token을 안전한 곳에 저장한다. 클라이언트에서 Token을 검증한 후, 인증을 완료한다. 정상적일 경우에 데이터를 넘겨준다.

  2. JWT(Access Token, Refresh Token)
    클라이언트에 사용자가 로그인하면 서버는 DB에서 사용자를 확인하고, Access Token과 Refresh Token을 발급한다. 클라이언트는 두 개의 토큰(Access, Refresh)을 안전한 곳에 저장한다. 클라이언트에서 Access Token과 함께 데이터를 요청한다. 서버는 Token을 검증한 후, 인증을 완료한다. 정상일 경우 데이터를 넘겨준다. 이까지는 Token 방식과 같다.
    만료된 Access Token으로 데이터를 요청한다. 서버에서는 만료를 확인하고, 클라이언트에 보낸다. 클라이언트에서는 Refresh Token으로 서버에 Access Token 발급을 요청한다.
    Refresh Token을 확인 후, 새로운 Access Token과 Refresh Token을 발급한다.

JMT 구조는 헤더, 내용, 서명으로 구성되어 있다.
헤더에는 토큰 타입과 암호 알고리즘 정보가 담겨 있다.
내용에는 토큰에 담을 정보가 들어있다. username과 유효기간을 넣는다.
서명에는 헤더와 내용을 합친 후 Secret Key로 해쉬하여 생성된다.
 토근 조작이 불가능하다. 서명 부분은 Secret key 모를 경우에 복화를 할 수 없다.

  1. OAuth
    사용자가 비밀번호를 노출하지 않고 다른 웹 사이트의 자신의 정보를 웹이나 애플리케이션에 접근 권한을 부여할 수 있는 개방형 표준이다. OAuth 인증을 통해 애플리케이션 API를 유저 대신에 접근할 수 있는 권한을 얻을 수 있다. OAuth의 인증은 API를 제공하는 서버에서 진행하고, 유저가 인증되었다는 Access Token을 발급한다. 그 발급된 Access token으로 Third Party 애플리케이션에서는 Service Provider의 API를 안전하고 쉽게 사용할 수 있게 되었다.
     아마존, 구글, 페이스북, 카카오, 네이버, 트위터

JMT기반 시스템 구현하기

app.js

  • npm install jsonwebtoken 설치
app.set('jwt-secret', 주소입력);
const auth_config = require('./주소/주소/주소');

주소/주소/주소안에 secret key 저장
secret key가 없으면 암호를 복호화 할 수 없다.

routes/api/auth/indes.js

const authMiddleware = require('./auth');
JMT위치 지정 
router.use('/check/', authMiddleware);

미들웨어를 통해 JMT 경로로 라우터 모듈을 마운트 하여 사용

routes/api/auth.js 이동

const jwt = require('jsonwebtoken');
// jwt 모듈 호출
const authMiddleware = (req, res, next) => {
    const token = req.headers['x-access-token'] || req.query.token;
// jwt의 헤더 부분
if(!token) {
    return res.status(403).json({
        success: false,
        errorcode: 3000,
        message: '토큰이 없습니다.'
    });
}

토근이 존재하지 않을 경우

const p = new Promise(
    (resolve, reject) => {
        jwt.verify(token, req.app.get('jwt-secret'), (err, decoded) => {
            if(err) reject(err);
            resolve(decoded)
        })
    }
);

토큰을 디코딩 하는 Promise 생성

Promise 함수 : 자바스크립트 비동기 처리에 사용되는 객체, 주로 서버에서 받아온 데이터를 화면에 표시할 때 사용한다.

프로미스의 3가지 상태

 Pending(대기) : 비동기 처리 로직이 아직 완료되지 않는 상태
 Fulfilled(이행) : 비동기 처리가 완료되어 프로미스가 결과 값을 변환해준 상태
 Rejected(실패) : 비동기 처리가 실패하거나 오류가 발생한 상태

Pending(대기)

const p = new Promise(
(resolve, reject) => {

new promise 메서드를 호출하면 대기 상태가 된다.

Fulfilled(이행) 
 jwt.verify(token, req.app.get('jwt-secret'), (err, decoded) => {
                if(err) reject(err);
                resolve(decoded)
            })
        }
    );

   p.then((decoded)=>{
        req.decoded = decoded;
        next();
    }).catch(onError)
};

이행 상태 시에 then()을 사용하여 처리 결과 값을 받을 수 있다.

Rejected(실패) 
    const onError = (error) => {
        res.status(403).json({
            success: false,
            errorcode: 3000,
            message: error.message
        })
    };

Reject를 호출하게 되면 실패 상태가 되고 catch로 err 결과 값을 받을 수 있다.

profile
개발 노트

0개의 댓글