-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: login and logout #15
Open
rlooo
wants to merge
2
commits into
develop
Choose a base branch
from
feature/login
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { PassportStatic } from 'passport' | ||
import { Strategy as KakaoStrategy } from 'passport-kakao' | ||
import { Strategy as GoogleStrategy } from 'passport-google-oauth20' | ||
import config from '@/config' | ||
import { findOrCreateUser } from '../services/v1/auth' | ||
import { User } from '@/models/user' | ||
import { GoogleProfile, KakaoProfile } from '@/types/oauth.profile' | ||
import { findUserById } from '@/services/v1/user' | ||
|
||
export default function configurePassport(passport: PassportStatic): void { | ||
passport.serializeUser((user: User, done) => { | ||
done(null, user._id) | ||
}) | ||
|
||
passport.deserializeUser(async (id: string, done) => { | ||
try { | ||
const user = await findUserById(id) | ||
done(null, user) | ||
} catch (err) { | ||
done(err, null) | ||
} | ||
}) | ||
|
||
passport.use( | ||
'kakao', | ||
new KakaoStrategy( | ||
{ | ||
clientID: config.kakao.clientId, | ||
clientSecret: config.kakao.clientSecret, | ||
callbackURL: config.kakao.redirectUri, | ||
}, | ||
async (_accessToken: string, _refreshToken: string, profile: KakaoProfile, done) => { | ||
try { | ||
const user: User = await findOrCreateUser('kakao', profile) | ||
return done(null, user) | ||
} catch (error) { | ||
return done(error, null) | ||
} | ||
}, | ||
), | ||
) | ||
|
||
passport.use( | ||
'google', | ||
new GoogleStrategy( | ||
{ | ||
clientID: config.google.clientId, | ||
clientSecret: config.google.clientSecret, | ||
callbackURL: config.google.redirectUri, | ||
}, | ||
async (_accessToken: string, _refreshToken: string, profile: GoogleProfile, done) => { | ||
try { | ||
const user: User = await findOrCreateUser('google', profile) | ||
return done(null, user) | ||
} catch (error) { | ||
return done(error, null) | ||
} | ||
}, | ||
), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { AuthFailureException } from '@/exceptions/AuthFailureException' | ||
import { LogoutFailedException } from '@/exceptions/LogoutFailedException ' | ||
import { User } from '@/models/user' | ||
import { generateJWT } from '@/services/v1/auth' | ||
import { Request, Response } from 'express' | ||
import passport from 'passport' | ||
|
||
export const authenticate = (provider: string) => { | ||
return passport.authenticate(provider, { scope: getScopes(provider) }) | ||
} | ||
|
||
export const callback = (provider: string) => { | ||
return [ | ||
passport.authenticate(provider, { failureRedirect: '/auth/failure' }), | ||
(req: Request, res: Response) => { | ||
const user = req.user as User | ||
const token = generateJWT(user) | ||
res.json({ token }) | ||
}, | ||
] | ||
} | ||
|
||
export const authFailure = (req: Request, res: Response) => { | ||
throw new AuthFailureException() | ||
} | ||
|
||
export const logout = (req: Request, res: Response) => { | ||
req.logout() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 의도하신 로그아웃 기능이 사용자 정보를 저장한 세션을 만료시키는 것이 맞을까요? |
||
|
||
req.session.destroy(err => { | ||
if (err) { | ||
throw new LogoutFailedException() | ||
} | ||
res.clearCookie('connect.sid') | ||
res.status(200).send() | ||
}) | ||
} | ||
|
||
const getScopes = (provider: string): string[] => { | ||
switch (provider) { | ||
case 'google': | ||
return ['profile', 'email'] | ||
case 'kakao': | ||
return ['profile_nickname'] | ||
default: | ||
return [] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,9 @@ | ||
import express, { Request, Response } from 'express' | ||
import asyncify from 'express-asyncify' | ||
import { Request, Response } from 'express' | ||
|
||
import { EnquiryModel } from '@/models/enquiry' | ||
|
||
const router = asyncify(express.Router()) | ||
|
||
// TODO: add verify user middleware | ||
router.post('/', async (req: Request, res: Response) => { | ||
export const createEnquiry = async (req: Request, res: Response) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이 부분은 왜 수정하신걸까요? |
||
const enquiry = await EnquiryModel.create({ | ||
userId: req.user._id, | ||
title: req.body.title, | ||
|
@@ -15,6 +12,4 @@ router.post('/', async (req: Request, res: Response) => { | |
res.status(200).json({ | ||
enquiryId: enquiry._id, | ||
}) | ||
}) | ||
|
||
export default router | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { HttpException } from '@/exceptions/HttpException' | ||
|
||
export class AuthFailureException extends HttpException { | ||
constructor() { | ||
super(401, 'Authentication Failed') | ||
Object.setPrototypeOf(this, AuthFailureException.prototype) | ||
Error.captureStackTrace(this, AuthFailureException) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { HttpError } from 'routing-controllers' | ||
|
||
export class HttpException extends HttpError { | ||
public status: number | ||
public message: string | ||
|
||
constructor(status: number, message: string) { | ||
super(status, message) | ||
this.status = status | ||
this.message = message | ||
} | ||
|
||
toJSON() { | ||
return { | ||
status: this.status, | ||
message: this.message, | ||
stack: this.stack, | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { HttpException } from '@/exceptions/HttpException' | ||
|
||
export class LogoutFailedException extends HttpException { | ||
constructor() { | ||
super(500, 'Failed to log out.') | ||
Object.setPrototypeOf(this, LogoutFailedException.prototype) | ||
Error.captureStackTrace(this, LogoutFailedException) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { HttpException } from '@/exceptions/HttpException' | ||
|
||
export class NotFoundRouteException extends HttpException { | ||
constructor() { | ||
super(404, 'Route not found') | ||
Object.setPrototypeOf(this, NotFoundRouteException.prototype) | ||
Error.captureStackTrace(this, NotFoundRouteException) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
import { AuthFailureException } from '@/exceptions/AuthFailureException' | ||
import { Request, Response, NextFunction } from 'express' | ||
|
||
export function ensureAuthenticated(req: Request, res: Response, next: NextFunction) { | ||
if (req.isAuthenticated()) { | ||
return next() | ||
} | ||
throw new AuthFailureException() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,18 @@ | ||
import mongoose from 'mongoose' | ||
import { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses' | ||
import { getModelForClass, prop } from '@typegoose/typegoose' | ||
import { TimeStamps } from '@typegoose/typegoose/lib/defaultClasses' | ||
|
||
export class User extends TimeStamps { | ||
public _id: mongoose.Types.ObjectId | ||
|
||
@prop({ required: true }) | ||
public nickname: string | ||
public nickname!: string | ||
|
||
@prop() | ||
public provider: string | ||
@prop({ required: true }) | ||
public provider!: string | ||
|
||
@prop() | ||
public providerId: string | ||
@prop({ required: true }) | ||
public providerId!: string | ||
} | ||
|
||
export const UserModel = getModelForClass(User) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { authenticate, authFailure, callback, logout } from '@/controllers/v1/auth' | ||
import express from 'express' | ||
import asyncify from 'express-asyncify' | ||
|
||
const router = asyncify(express.Router()) | ||
|
||
const providers = ['kakao', 'google'] | ||
|
||
providers.forEach(provider => { | ||
router.get(`/${provider}`, authenticate(provider)) | ||
router.get(`/${provider}/callback`, ...callback(provider)) | ||
}) | ||
|
||
router.get('/failure', authFailure) | ||
|
||
router.post('/logout', logout) | ||
|
||
export default router |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import express from 'express' | ||
import asyncify from 'express-asyncify' | ||
import { createEnquiry } from '@/controllers/v1/enquiries' | ||
|
||
const router = asyncify(express.Router()) | ||
|
||
// TODO: add verify user middleware | ||
router.post('/', createEnquiry) | ||
|
||
export default router |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import express from 'express' | ||
import asyncify from 'express-asyncify' | ||
import { ensureAuthenticated } from '@/middlewares/v1/auth' | ||
import { logout } from '@/controllers/v1/auth' | ||
|
||
const router = asyncify(express.Router()) | ||
|
||
router.get('/logout', logout) | ||
|
||
router.get('/profile', ensureAuthenticated, (req, res) => { | ||
const user = req.user | ||
res.json({ user }) | ||
}) | ||
|
||
export default router |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
세션을 로그인 과정에서 어떻게 이용하시나요?
oauth 로그인 이후에, jwt 를 기준으로 저희만의 jwt로 sign 해서 클라이언트에게 전달하는 로직으로 확인해서요..!