├── .gitignore ├── README.md ├── auth.js ├── package.json ├── server.js └── views ├── app.html └── login.html /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # koa-passport-example 2 | 3 | Example for [koa-passport](https://github.com/rkusa/koa-passport) 4 | 5 | koa-passport version | koa version | branch 6 | --------------------- | ------------| ---------------- 7 | 1.x | 1.x | koa-passport@1.x 8 | 2.x | 2.x | koa-passport@2.x 9 | 3.x | 2.x | master 10 | 11 | ## Other Examples 12 | 13 | ## Note 14 | 15 | * If your node version greater than or equal 8.4.0 then replace "start": "node --harmony-async-await server.js" with "start": "node server.js" 16 | 17 | ### Integrating with databases 18 | 19 | * [Example with mongoose module for MongoDB](https://github.com/mapmeld/koa-passport-example) 20 | 21 | ### koa-router 22 | 23 | * [Example with koa-router](https://github.com/mjhea0/koa-passport-example) 24 | * Full-featured example with koa-router, koa-session, bcrypt, postgres, and koa-redis - [blog post](http://mherman.org/blog/2018/01/02/user-authentication-with-passport-and-koa), [code](https://github.com/mjhea0/node-koa-api) 25 | * [Another Full-featured example](https://github.com/7kmCo/koa-example) with koa-router, koa-session, bcrypt, koa-passport with local, google, facebook and twitter strategies, mysql with relationship example 26 | -------------------------------------------------------------------------------- /auth.js: -------------------------------------------------------------------------------- 1 | const passport = require('koa-passport') 2 | 3 | const fetchUser = (() => { 4 | // This is an example! Use password hashing in your project and avoid storing passwords in your code 5 | const user = { id: 1, username: 'test', password: 'test' } 6 | return async function() { 7 | return user 8 | } 9 | })() 10 | 11 | passport.serializeUser(function(user, done) { 12 | done(null, user.id) 13 | }) 14 | 15 | passport.deserializeUser(async function(id, done) { 16 | try { 17 | const user = await fetchUser() 18 | done(null, user) 19 | } catch(err) { 20 | done(err) 21 | } 22 | }) 23 | 24 | const LocalStrategy = require('passport-local').Strategy 25 | passport.use(new LocalStrategy(function(username, password, done) { 26 | fetchUser() 27 | .then(user => { 28 | if (username === user.username && password === user.password) { 29 | done(null, user) 30 | } else { 31 | done(null, false) 32 | } 33 | }) 34 | .catch(err => done(err)) 35 | })) 36 | 37 | const FacebookStrategy = require('passport-facebook').Strategy 38 | passport.use(new FacebookStrategy({ 39 | clientID: 'your-client-id', 40 | clientSecret: 'your-secret', 41 | callbackURL: 'http://localhost:' + (process.env.PORT || 3000) + '/auth/facebook/callback' 42 | }, 43 | function(token, tokenSecret, profile, done) { 44 | // retrieve user ... 45 | fetchUser().then(user => done(null, user)) 46 | } 47 | )) 48 | 49 | const TwitterStrategy = require('passport-twitter').Strategy 50 | passport.use(new TwitterStrategy({ 51 | consumerKey: 'your-consumer-key', 52 | consumerSecret: 'your-secret', 53 | callbackURL: 'http://localhost:' + (process.env.PORT || 3000) + '/auth/twitter/callback' 54 | }, 55 | function(token, tokenSecret, profile, done) { 56 | // retrieve user ... 57 | fetchUser().then(user => done(null, user)) 58 | } 59 | )) 60 | 61 | const GoogleStrategy = require('passport-google-auth').Strategy 62 | passport.use(new GoogleStrategy({ 63 | clientId: 'your-client-id', 64 | clientSecret: 'your-secret', 65 | callbackURL: 'http://localhost:' + (process.env.PORT || 3000) + '/auth/google/callback' 66 | }, 67 | function(token, tokenSecret, profile, done) { 68 | // retrieve user ... 69 | fetchUser().then(user => done(null, user)) 70 | } 71 | )) 72 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "koa-passport-example", 3 | "author": "Markus Ast =7" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /server.js: -------------------------------------------------------------------------------- 1 | const Koa = require('koa') 2 | const app = new Koa() 3 | 4 | // trust proxy 5 | app.proxy = true 6 | 7 | // sessions 8 | const session = require('koa-session') 9 | app.keys = ['your-session-secret'] 10 | app.use(session({}, app)) 11 | 12 | // body parser 13 | const bodyParser = require('koa-bodyparser') 14 | app.use(bodyParser()) 15 | 16 | // authentication 17 | require('./auth') 18 | const passport = require('koa-passport') 19 | app.use(passport.initialize()) 20 | app.use(passport.session()) 21 | 22 | // routes 23 | const fs = require('fs') 24 | const route = require('koa-route') 25 | 26 | app.use(route.get('/', function(ctx) { 27 | ctx.type = 'html' 28 | ctx.body = fs.createReadStream('views/login.html') 29 | })) 30 | 31 | app.use(route.post('/custom', function(ctx) { 32 | return passport.authenticate('local', function(err, user, info, status) { 33 | if (user === false) { 34 | ctx.body = { success: false } 35 | ctx.throw(401) 36 | } else { 37 | ctx.body = { success: true } 38 | return ctx.login(user) 39 | } 40 | })(ctx) 41 | })) 42 | 43 | // POST /login 44 | app.use(route.post('/login', 45 | passport.authenticate('local', { 46 | successRedirect: '/app', 47 | failureRedirect: '/' 48 | }) 49 | )) 50 | 51 | app.use(route.get('/logout', function(ctx) { 52 | ctx.logout() 53 | ctx.redirect('/') 54 | })) 55 | 56 | app.use(route.get('/auth/facebook', 57 | passport.authenticate('facebook') 58 | )) 59 | 60 | app.use(route.get('/auth/facebook/callback', 61 | passport.authenticate('facebook', { 62 | successRedirect: '/app', 63 | failureRedirect: '/' 64 | }) 65 | )) 66 | 67 | app.use(route.get('/auth/twitter', 68 | passport.authenticate('twitter') 69 | )) 70 | 71 | app.use(route.get('/auth/twitter/callback', 72 | passport.authenticate('twitter', { 73 | successRedirect: '/app', 74 | failureRedirect: '/' 75 | }) 76 | )) 77 | 78 | app.use(route.get('/auth/google', 79 | passport.authenticate('google') 80 | )) 81 | 82 | app.use(route.get('/auth/google/callback', 83 | passport.authenticate('google', { 84 | successRedirect: '/app', 85 | failureRedirect: '/' 86 | }) 87 | )) 88 | 89 | // Require authentication for now 90 | app.use(function(ctx, next) { 91 | if (ctx.isAuthenticated()) { 92 | return next() 93 | } else { 94 | ctx.redirect('/') 95 | } 96 | }) 97 | 98 | app.use(route.get('/app', function(ctx) { 99 | ctx.type = 'html' 100 | ctx.body = fs.createReadStream('views/app.html') 101 | })) 102 | 103 | // start server 104 | const port = process.env.PORT || 3000 105 | app.listen(port, () => console.log('Server listening on', port)) 106 | -------------------------------------------------------------------------------- /views/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | koa-passport example 7 | 8 | 9 |

App

10 |

You are authenticated ... logout

11 | 12 | -------------------------------------------------------------------------------- /views/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | koa-passport example 7 | 8 | 9 |
10 |

11 | 14 |

15 |

16 | 19 |

20 |

21 | 22 |

23 |

24 | Sign in with Facebook Sign in with Twitter Sign in with Google 25 |

26 |
27 | 28 | 29 | --------------------------------------------------------------------------------