Firebase auth로 소셜 로그인 구현 시 서비스 서버의 동작 | 오늘의 맛집은? 메이크어케이크

Sanghwa Lee·2022년 3월 2일
3
post-thumbnail

서비스 자체 로그인만 주구장창 해왔고, 구글 로그인 구현하다 실패한 기억이 있었다. 근데 보안이 안전하고 인증이 쉽다는 점이나 ... 기업 내에서 개발해야 하는데 주먹구구식 로그인 기능을 넣으면 안 되니까앱 스토어는 애플 로그인 필수이기도 하고ㅡㅡ 소셜 로그인 재도전!

Authentication

Firebase authentication 기능을 사용했다. 이번에 처음 알게 된 기능인데 서비스 서버에서 auth api를 따로 만들지 않아도 돼서 편했다. 그리고 Firebase 프로젝트 내에서 로그인 업체(method)를 선택하면 알아서 연결이 된다. 우리는 구글, 애플을 선택했다. 그 업체들에서 로그인하면 Firebase에선 unique한 토큰을 발행해 반환해준다. 이 밖에도 auth 관련 기능들을 사용할 수 있다. 이건 다 프론트에서 하는 거였다.

Service server

로그인할 때 유저의 토큰을 받아와 자체 DB에 저장한다. 끗ㅋ개꿀 여기에 이미 가입한 유저 토큰인지 판별하는 로직만 추가했다. 이렇게 할 게 없는데 글까지 쓰는 이유는? 내가 뭘 해야 할지 모를 때 관련 글이 하나도 없었기 때문이다. 내가 나중에 또 볼 수도 있고.

아래는 로그인에 필요한 서비스 내 api들이다.

POST /api/users/login

router.post('/login', (req, res) => {
    User.findOne({ firebaseId: req.body.firebaseId }, (err, user) => {
        if (err) return res.status(403).json({ success: false, err });

        if (!user) {
            return res.status(400).json({
                loginSuccess: false,
                message: '가입되지 않은 유저입니다.',
            });
        }

        if (!(user.deviceToken).includes(req.body.deviceToken)) {
            User.findOneAndUpdate({
                _id: user._id,
            }, 
            { $set: { deviceToken: [...user.deviceToken, req.body.deviceToken] } }, 
            { new: true }, (err, user) => {
                if (err) return res.status(403).json({ err });
            });
        }

        return res.status(200).json({
            loginSuccess: true,
            serviceId: user._id,
            nickname: user.nickname,
            firebaseId: user.firebaseId,
            agoraId: user.agoraId,
            blockList: user.block
        });
    });
});

가입되지 않은 유저이면(Error code: 400) 회원가입을 한다.

POST /api/users/register

router.post('/register', (req, res) => {
    if (!req.body.firebaseId) {
        return res.status(412).json({
            success: false,
            message: '로그인되지 않았습니다.',
        });
    }

    User.findOne({ firebaseId: req.body.firebaseId }, (err, user) => {
        if (err) return res.status(400).json({ success: false, err });

        if (user) {
            return res.status(409).json({
                success: false,
                message: '이미 가입된 유저입니다.',
            });
        }

        const nickname = req.body.nickname;
        if (!nickname) return res.status(411).json({
            message: "닉네임을 입력해주세요."
        });
        if (wordchx.wordchk1(nickname) || wordchx.wordchk2(nickname)) {
            return res.status(406).json({
                message: "닉네임에 부적절한 표현이 있습니다."
            });
        }

        User.findOne({ nickname: req.body.nickname }, (err, user) => {
            if (err) return res.status(400).json({ success: false, err });

            if (user) {
                return res.status(409).json({
                    success: false,
                    message: '이미 존재하는 닉네임입니다.',
                });
            }

            const newUser = new User(req.body);
        
            newUser.save((err, userInfo) => {
                if (err) return res.status(400).json({ success: false, err });
    
                return res.status(200).json({
                    loginSuccess: true,
                    serviceId: userInfo._id,
                    nickname: userInfo.nickname,
                    firebaseId: userInfo.firebaseId,
                    agoraId: userInfo.agoraId
                });
            });
        })
    });
});

로그아웃은 Firebase auth 기능에 있다. 서버 진짜 할 거 없쥬?

오늘의 맛집

판교에 있는 메이크어케이크 이다. 우유 케익 맛집!

순수 우유 케익이고 여기에 과일이 들어가든 안 들어가든 한다. 이 중에서 베스트인 베리 케익이 제일 맛있었다. 딸기즙이 나와서 크림이 더 달달해졌기 때문인듯? 근데 엄청 비싸다. 일산에 내가 좋아하는 케익 맛집 카페가 있는데 거기보다도 약간 더 비쌌다. 가격 조심~ 분위기는 좋았고 의자도 편했다. 이야기 나누기 좋았던 것 같다.

다 놀고 나왔을 때 얼그레이 케익도 나왔는데 먹어보고 싶었다. 근데 얼그레이가 얼그레이겠지? 아니야 여긴 좀 다르려나?? 그래도 우유가 더 특색있고 맛있었을 수도!

사실 메이크어케이크 말고도 쓰고 싶은 맛집들이 많았는데 인턴 끝난 날에 간 곳이고 아직 인턴이 끝난 데에 공허함을 갖고 있어서 여기를 써봤다.

profile
맛집 보고 가세요 😀

2개의 댓글

comment-user-thumbnail
2022년 3월 7일

짱 안쉬운데요

1개의 답글