-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
First commit - working passport oauth
- Loading branch information
0 parents
commit 7fb850c
Showing
7 changed files
with
278 additions
and
0 deletions.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
npm-debug.log* |
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,49 @@ | ||
# passport-discord | ||
|
||
Passport strategy for authentication with [Discord](http://discordapp.com) through the OAuth 2.0 API. | ||
|
||
At time of writing there is no official page/documentation for this, so information can be read off the example project, such as how to set up an API application [here](http://github.com/vishnevskiy/discord-oauth2-example). | ||
|
||
## Usage | ||
`npm install passport-discord --save` | ||
|
||
#### Configure Strategy | ||
The Discord authentication strategy authenticates users via a Discord user account and OAuth 2.0 token(s). A Discord API client ID, secret and redirect URL must be supplied when using this strategy. The strategy also requires a `verify` callback, which receives the access token and an optional refresh token, as well as a `profile` which contains the authenticated Discord user's profile. The `verify` callback must also call `cb` providing a user to complete the authentication. | ||
|
||
```javascript | ||
var DiscordStrategy = require('passport-discord').Strategy; | ||
|
||
passport.use(new DiscordStrategy( | ||
{ | ||
clientID: 'id', | ||
clientSecret: 'secret', | ||
callbackURL: 'callbackURL' | ||
}, | ||
function(accessToken, refreshToken, profile, cb) { | ||
User.findOrCreate({ discordId: profile.id }, function(err, user) { | ||
return cb(err, user); | ||
}); | ||
} | ||
)); | ||
``` | ||
|
||
#### Authentication Requests | ||
Use `passport.authenticate()`, and specify the `'discord'` strategy to authenticate requests. | ||
|
||
Foe example, as a route middleware in an Express app: | ||
|
||
```javascript | ||
app.get('/auth/discord', passport.authenticate('discord')); | ||
app.get('/auth/discord/callback', passport.authenticate('discord', { | ||
failureRedirect: '/' | ||
}), function(req, res) { | ||
res.redirect('/secretstuff') // Successful auth | ||
}); | ||
``` | ||
|
||
|
||
## Examples | ||
An Express server example can be found in the `/example` directory. Be sure to `npm install` in that directory to get the dependencies. | ||
|
||
## Credits | ||
* Jared Hanson - used passport-github to understand passport more and kind of as a base. |
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,17 @@ | ||
{ | ||
"name": "passport-discord-example", | ||
"version": "0.1.0", | ||
"description": "", | ||
"main": "server.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"start": "node server.js" | ||
}, | ||
"author": "Nicholas Tay <[email protected]> (http://nicholastay.github.io)", | ||
"license": "ISC", | ||
"dependencies": { | ||
"express": "^4.13.4", | ||
"express-session": "^1.13.0", | ||
"passport": "^0.3.2" | ||
} | ||
} |
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,57 @@ | ||
var express = require('express') | ||
, session = require('express-session') | ||
, passport = require('passport') | ||
, Strategy = require('../lib').Strategy | ||
, app = express(); | ||
|
||
passport.serializeUser(function(user, done) { | ||
done(null, user); | ||
}); | ||
passport.deserializeUser(function(obj, done) { | ||
done(null, obj); | ||
}); | ||
|
||
var scopes = ['identify', 'email', /* 'connections', (it is currently broken) */ 'guilds', 'guilds.join']; | ||
|
||
passport.use(new Strategy({ | ||
clientID: '', | ||
clientSecret: '', | ||
callbackURL: 'http://localhost:5000/callback', | ||
scope: scopes | ||
}, function(accessToken, refreshToken, profile, done) { | ||
process.nextTick(function() { | ||
return done(null, profile); | ||
}); | ||
})); | ||
|
||
app.use(session({ | ||
secret: 'keyboard cat', | ||
resave: false, | ||
saveUninitialized: false | ||
})); | ||
app.use(passport.initialize()); | ||
app.use(passport.session()); | ||
app.get('/', passport.authenticate('discord', { scope: scopes }), function(req, res) {}); | ||
app.get('/callback', | ||
passport.authenticate('discord', { failureRedirect: '/' }), function(req, res) { res.redirect('/info') } // auth success | ||
); | ||
app.get('/logout', function(req, res) { | ||
req.logout(); | ||
res.redirect('/'); | ||
}); | ||
app.get('/info', checkAuth, function(req, res) { | ||
//console.log(req.user) | ||
res.json(req.user); | ||
}); | ||
|
||
|
||
function checkAuth(req, res, next) { | ||
if (req.isAuthenticated()) return next(); | ||
res.send('not logged in :('); | ||
} | ||
|
||
|
||
app.listen(5000, function (err) { | ||
if (err) return console.log(err) | ||
console.log('Listening at http://localhost:5000/') | ||
}) |
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,14 @@ | ||
/** | ||
* Module dependencies. | ||
*/ | ||
var Strategy = require('./strategy'); | ||
|
||
/** | ||
* Expose `Strategy` directly from package. | ||
*/ | ||
exports = module.exports = Strategy; | ||
|
||
/** | ||
* Export constructors. | ||
*/ | ||
exports.Strategy = Strategy; |
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,109 @@ | ||
/** | ||
* Dependencies | ||
*/ | ||
var OAuth2Strategy = require('passport-oauth2') | ||
, InternalOAuthError = require('passport-oauth2').InternalOAuthError | ||
, util = require('util'); | ||
|
||
/** | ||
* `Strategy` constructor. | ||
* | ||
* The Discord authentication strategy authenticates requests by delegating to | ||
* Discord via the OAuth2.0 protocol | ||
* | ||
* Applications must supply a `verify` callback which accepts an `accessToken`, | ||
* `refreshToken` and service-specific `profile`, and then calls the `cb` | ||
* callback supplying a `user`, which should be set to `false` if the | ||
* credentials are not valid. If an exception occured, `err` should be set. | ||
* | ||
* Options: | ||
* - `clientID` OAuth ID to discord | ||
* - `clientSecret` OAuth Secret to verify client to discord | ||
* - `callbackURL` URL that discord will redirect to after auth | ||
* - `scope` Array of permission scopes to request | ||
* Valid discord scopes include: 'identity', 'email', 'connections', 'guilds', 'guilds.join' | ||
* | ||
* @constructor | ||
* @param {object} options | ||
* @param {function} verify | ||
* @access public | ||
*/ | ||
function Strategy(options, verify) { | ||
options = options || {}; | ||
options.authorizationURL = options.authorizationURL || 'https://discordapp.com/api/oauth2/authorize'; | ||
options.tokenURL = options.tokenURL || 'https://discordapp.com/api/oauth2/token'; | ||
options.scopeSeparator = options.scopeSeparator || ' '; | ||
|
||
OAuth2Strategy.call(this, options, verify); | ||
this.name = 'discord'; | ||
this._oauth2.useAuthorizationHeaderforGET(true); | ||
} | ||
|
||
/** | ||
* Inherits from `OAuth2Strategy` | ||
*/ | ||
util.inherits(Strategy, OAuth2Strategy); | ||
|
||
/** | ||
* Retrieve user profile from Discord. | ||
* | ||
* This function constructs a normalized profile, with the following properties: | ||
* | ||
* - `something` ayy lmao | ||
* | ||
* @param {string} accessToken | ||
* @param {function} done | ||
* @access protected | ||
*/ | ||
Strategy.prototype.userProfile = function(accessToken, done) { | ||
var self = this; | ||
this._oauth2.get('https://discordapp.com/api/users/@me', accessToken, function(err, body, res) { | ||
if (err) { | ||
return done(new InternalOAuthError('Failed to fetch the user profile.', err)) | ||
} | ||
|
||
try { | ||
var parsedData = JSON.parse(body); | ||
} | ||
catch (e) { | ||
return done(new Error('Failed to parse the user profile.')); | ||
} | ||
|
||
var profile = parsedData; // has the basic user stuff | ||
profile.provider = 'discord'; | ||
|
||
self.checkScope('connections', accessToken, function(errx, connections) { | ||
if (errx) done(errx); | ||
if (connections) profile.connections = connections; | ||
self.checkScope('guilds', accessToken, function(erry, guilds) { | ||
if (erry) done(erry); | ||
if (guilds) profile.guilds = guilds; | ||
|
||
return done(null, profile) | ||
}); | ||
}); | ||
}); | ||
}; | ||
|
||
Strategy.prototype.checkScope = function(scope, accessToken, cb) { | ||
if (this._scope && this._scope.indexOf(scope) !== -1) { | ||
this._oauth2.get('https://discordapp.com/api/users/@me/' + scope, accessToken, function(err, body, res) { | ||
if (err) return cb(new InternalOAuthError('Failed to fetch user\'s ' + scope, err)); | ||
try { | ||
var json = JSON.parse(body); | ||
} | ||
catch (e) { | ||
return cb(new Error('Failed to parse user\'s ' + scope)); | ||
} | ||
cb(null, json); | ||
}); | ||
} else { | ||
cb(null, null); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* Expose `Strategy`. | ||
*/ | ||
module.exports = Strategy; |
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,30 @@ | ||
{ | ||
"name": "passport-discord", | ||
"version": "0.1.0", | ||
"description": "Passport strategy for authentication with Discord (discordapp.com)", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/nicholastay/passport-discord.git" | ||
}, | ||
"keywords": [ | ||
"passport", | ||
"discord", | ||
"auth", | ||
"authentication", | ||
"authn", | ||
"identity" | ||
], | ||
"author": "Nicholas Tay <[email protected]> (http://nicholastay.github.io)", | ||
"license": "ISC", | ||
"bugs": { | ||
"url": "https://github.com/nicholastay/passport-discord/issues" | ||
}, | ||
"homepage": "https://github.com/nicholastay/passport-discord#readme", | ||
"dependencies": { | ||
"passport-oauth2": "^1.2.0" | ||
} | ||
} |