이번에는 Firebase 인증(Authentication) 기능을 이용하여, 실제 게시판처럼 로그인한 사용자만 사용하도록 작성한다.


1. 시작하기

2. Realtime Database 기반 게시판

3. Cloud Firestore (beta) 기반 게시판

4. 로그인 (authentication) 기능 추가

5. 무료 호스팅(Firebase Hosting)으로 배포 I, II


Firebase에서는 인증과 관련된 아주 많은 기능을 제공하고 있다.

회원 가입, 회원 리스트 등의 기능뿐만 아니라 페이스북, Gmail등의 로그인 기능 등을 제공하고 있다.

너무 많은 기능이 있고, 이것을 문서로 제공해서 오히려 익히기 어렵게 느껴지기 때문에 여기에서는 로그인 기능만을 정리한다.

따라서, 앞서 작성한 Cloud Firestore 기반 게시판에 로그인 기능과 로그인한 사용자만 사용하도록 구현한다.

관련된 상세한 설명은 Firebase 인증 문서를 참고하면 되고, 관련 소스는 GitHub에서 받을 수 있다.


먼저, Firebase 콘솔에서 Authentication(인증)을 선택하고, 화면 하단에 있는 [로그인 방법 설정]을 선택한다.


로그인 제공업체 리스트에서 [이메일/비밀번호]를 선택한다.


첫 번째로 보이는 [사용 설정]을 활성화 시키고 저장한다.


[사용자] 탭을 클릭해서 [사용자 추가] 버튼을 클릭하고,

실행된 팝업창에서 로그인 ID (이메일)와 비번번호를 입력한다.


다시 화면 중앙에 있는 [사용자 추가] 버튼을 클릭해서 사용자를 생성한다.


간단하게 사용자(test@test.com)를 생성하였다.

프로그램으로 생성하고 관리하는 방법은 Firebase 문서를 참고하면 된다.

아쉬운 점은 사용자 이름(별명-displayName)을 입력하는 방법은 프로그램으로 처리해야 한다는 것이다.


board2.js와 board2 폴더를 복사해서 board3.js와 board3 폴더를 생성한다.

app.js에서 다음과 같이 기존 컨트롤들은 주석 처리하고, board3을 활성화 한다.

app.use('/', indexRouter);
app.use('/users', usersRouter);
//app.use('/board1', require('./routes/board1'));
//app.use('/board2', require('./routes/board2'));
app.use('/board3', require('./routes/board3'));

app.js


로그인 기능을 구현하기 위해 다음 코드를 board3.js에 추가한다.

사용자의 로그인 정보를 입력받을 화면(loginForm)와 로그인 처리를 수행할(loginChk) 컨트롤을 구현한 것이다.

router.get('/loginForm', function(req, res, next) {
    res.render('board3/loginForm');
});

router.post('/loginChk', function(req, res, next) {
    firebase.auth().signInWithEmailAndPassword(req.body.id, req.body.passwd)
       .then(function(firebaseUser) {
           res.redirect('boardList');
       })
      .catch(function(error) {
          res.redirect('loginForm');
      });   
});

용자의 로그인 정보를 입력받을 화면(loginForm)은 별다른 처리 없이 HTML (loginForm.ejs) 페이지를 호출한다.


loginForm.ejs

사용자의 아이디(id)와 비밀번호(passwd)을 입력받도록 구성하면 된다 [라인 17, 21].


loginChk에서는 signInWithEmailAndPassword 함수로 사용자가 입력한 아이디와 비밀번호를 Firebase에 전송해서

맞으면 (then) 게시판 리스트로 가고, 틀리면(catch) 다시 입력하도록 구현했다.


http://localhost:3000/board3/loginForm로 접속해서 로그인이 잘되는지 확인해 본다.

앞서 Firebase 콘솔에서 입력한 아이디(test@test.com)와 비밀번호(test1234)을 이용해서 확인하면 된다.


board3.js 파일에 다음과 같이 로그인되지 않았으면 (! firebase.auth().currentUser),

로그인 창으로 이동하는(res.redirect('loginForm')) 코드를 추가한다.

~~ 생략 ~~

router.get('/boardList', function(req, res, next) {
    if (!firebase.auth().currentUser) {
        res.redirect('loginForm');
        return;
    }
    db.collection('board').orderBy("brddate", "desc").get()
          .then((snapshot) => {
    ~~ 생략 ~~   
});


router.get('/boardRead', function(req, res, next) {
    if (!firebase.auth().currentUser) {
        res.redirect('loginForm');
        return;
    }
   
    db.collection('board').doc(req.query.brdno).get()
    ~~ 생략 ~~   
});

router.get('/boardForm', function(req,res,next){
    if (!firebase.auth().currentUser) {
        res.redirect('loginForm');
        return;
    }
   
    ~~ 생략 ~~   
});

router.post('/boardSave', function(req,res,next){
    var user = firebase.auth().currentUser;
    if (!user) {
        res.redirect('loginForm');
        return;
    }
   
    var postData = req.body;
    if (!postData.brdno) {  // new
        postData.brddate = Date.now();
        var doc = db.collection("board").doc();
        postData.brdno = doc.id;
        postData.brdwriter = user.email;
        doc.set(postData);
    ~~ 생략 ~~   
});

router.get('/boardDelete', function(req,res,next){
    if (!firebase.auth().currentUser) {
        res.redirect('loginForm');
        return;
    }
   
    ~~ 생략 ~~   
});

board3.js

로그인 여부를 확인하는 코드는 모두 동일하다.

현재 로그인한 사용자(currentUser)가 있으면 로그인한 상태로 판단한다.

다만, boardSave에서는 조금 차이가 있는데,

현재 로그인한 사용자(currentUser)를 user 변수로 받아서 사용한다.

user 변수로 사용하는 이유는 작성자(brdwriter) 필드에 아이디(email)을 넣어주기 위해서 이다.

이전에는 사용자를 확인할 수 없어서 글 작성시 사용자가 입력했지만,

로그인 기능을 구현하였기 때문에, 위 그림과 같이 별도로 입력받지 않고 로그인한 정보를 이용한다.


새로운 글을 추가하면 다음과 같이 작성자(writer)에 현재 로그인한 사용자의 아이디가 나타난다.

이상으로 간단하게 로그인 기능과 로그인한 사용자만 글을 읽고 쓰도록 구현했다.

자신의 글만 수정하고 삭제 하는 등의 기능도 구현해 보면 실력향상에 도움이 될 것이다.

회원 관리 기능들도 구현해서 사용자의 이름(displayName)을 사용할 수 있도록 하면 제법 그럴 듯 하게 보일 것이다.


+ Recent posts