Skip to content

Commit

Permalink
Merge pull request #60 from rockpell/feature/github-login
Browse files Browse the repository at this point in the history
Feature/GitHub login
  • Loading branch information
rockpell committed Nov 26, 2020
2 parents e4ba110 + a5a6337 commit 6d025ba
Show file tree
Hide file tree
Showing 16 changed files with 532 additions and 3 deletions.
7 changes: 6 additions & 1 deletion backend/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import mongoose from 'mongoose'
import controller from './controller'
import statusCode from './util/statusCode'
import resMessage from './util/resMessage'
import passport from 'passport'
import passportConfig from './config/passport'
import './chatServer'
import cors from 'cors'

Expand All @@ -26,8 +28,11 @@ app.use(logger('dev'))
app.use(cors({ origin: true, credentials: true }))
app.use(express.json())
app.use(express.urlencoded({ extended: false }))
app.use(cookieParser())
app.use(express.static(path.join(__dirname, '../dist')))
app.use(cookieParser(process.env.COOKIE_SECRET))
app.use(passport.initialize())
app.use(cors({ origin: true, credentials: true }))
passportConfig()

app.use('/api', controller)
app.use('/docs', express.static(path.join(__dirname, './docs')))
Expand Down
87 changes: 87 additions & 0 deletions backend/config/passport.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
const passport = require('passport')
const GitHubStrategy = require('passport-github').Strategy
const JWTStrategy = require('passport-jwt').Strategy
const { User } = require('../model/User')

require('dotenv').config()

const githubStrategyOption = {
clientID: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
callbackURL: process.env.GITHUB_CALLBACK_URL,
}

async function gitStrategyLogin(profiles) {
try {
let user = await User.findOne({ OAuthId: profiles.id })
if (user === null) {
const data = await User.create({
OAuthId: profiles.id,
fullName: profiles.username,
isDeleted: false,
})
return {
success: true,
id: data._id,
}
}
return {
success: true,
id: user._id,
}
} catch (err) {
return { success: false }
}
}

async function githubVerify(accessToken, refreshToken, profile, done) {
try {
const result = await gitStrategyLogin(profile)
const user = { id: result.id }

if (result.success) {
return done(null, user)
}
return done(null, false, { message: 'κΉƒν—ˆλΈŒ λ‘œκ·ΈμΈμ— μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.' })
} catch (err) {
return done(null, false, { message: 'GitHub verify err λ°œμƒ' })
}
}

const cookieExtractor = req => {
if (req.signedCookies) return req.signedCookies.token
if (req.cookies) return req.cookies
}

const isExist = async userId => {
try {
let user = await User.findOne({ _id: userId })
return {
success: true,
id: user._id,
}
} catch (err) {
return { success: false }
}
}

const jwtStrategyOption = {
jwtFromRequest: cookieExtractor,
secretOrKey: process.env.JWT_SECRET,
}
async function jwtVerify(payload, done) {
try {
const result = await isExist(payload.id)
if (!result.success) {
return done(null, false, { message: 'JWT 토큰 인증에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.' })
}
return done(null, result)
} catch (err) {
return done(null, false, { message: 'JWT verify err λ°œμƒ' })
}
}

module.exports = () => {
passport.use(new GitHubStrategy(githubStrategyOption, githubVerify))
passport.use(new JWTStrategy(jwtStrategyOption, jwtVerify))
}
3 changes: 3 additions & 0 deletions backend/controller/index.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import express from 'express'
import userController from './user'
import channelController from './channel'

const router = express.Router()

router.use('/channel', channelController)

router.use('/user', userController)

module.exports = router
9 changes: 9 additions & 0 deletions backend/controller/user/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import express from 'express'
const router = express.Router()
const controller = require('./userController')

router.get('/sign-in/github', controller.githubLogin)
router.get('/sign-in/github/callback', controller.githubCallback)
router.get('/auth', controller.authCheck)

module.exports = router
40 changes: 40 additions & 0 deletions backend/controller/user/userController.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const passport = require('passport')
const jwt = require('jsonwebtoken')

exports.githubLogin = passport.authenticate('github')

exports.githubCallback = async (req, res, next) => {
const frontHost = process.env.FRONTEND_HOST
passport.authenticate('github', (err, id) => {
if (err || !id) {
return res.status(200).redirect(frontHost)
}
req.login(id, { session: false }, err => {
if (err) {
res.send(err)
}

const token = jwt.sign(id, process.env.JWT_SECRET, { expiresIn: '1H' })
res.cookie('token', token, {
maxAge: 1000 * 60 * 60,
httpOnly: true,
signed: true,
})
return res.status(200).redirect(frontHost)
})
})(req, res)
}

exports.authCheck = (req, res) => {
let token = req.signedCookies.token
if (token) {
try {
let decoded = jwt.verify(token, process.env.JWT_SECRET)
return res.json({ verify: true })
} catch (err) {
return res.json({ verify: false })
}
} else {
return res.json({ verify: false, message: 'token does not exist' })
}
}
42 changes: 42 additions & 0 deletions backend/docs/swagger.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,48 @@ paths:
description: bad request
default:
description: Default error sample response
/api/user/sign-in/github:
summary: workspace user login
description: selectworkspace user login
post:
summary: workspace user login
description: workspace user login
operationId: ''
parameters:
- name: oauthId
in: query
description: workspace user id
required: true
explode: true
schema:
type: integer
responses:
'200':
description: signin success
'400':
description: bad input parameter
/api/user/sign-out:
summary: workspace user signout
description: selectworkspace user signout
delete:
summary: workspace user signout
description: workspace user signout
operationId: ''
parameters:
- name: workspaceUserInfoId
in: query
description: workspace user id
required: true
explode: true
schema:
type: integer
responses:
'200':
description: search results matching criteria
'400':
description: bad input parameter


components:
schemas:
InventoryItem:
Expand Down
12 changes: 12 additions & 0 deletions backend/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const passport = require('passport')
require('dotenv').config()

exports.Auth = (req, res, next) => {
passport.authenticate('jwt', { session: false }, (err, user) => {
if (err || !user || !user.success) {
next({ status: 403, message: 'auth error' })
}
req.user = user
next()
})(req, res, next)
}
Loading

0 comments on commit 6d025ba

Please sign in to comment.