forked from reneweb/oauth2orize_authorization_grant_example
-
Notifications
You must be signed in to change notification settings - Fork 0
/
oauth.js
120 lines (101 loc) · 4.56 KB
/
oauth.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
var oauth2orize = require('oauth2orize')
, passport = require('passport')
, db = require('./db').db()
, crypto = require('crypto')
, utils = require("./utils")
, bcrypt = require('bcrypt')
// create OAuth 2.0 server
var server = oauth2orize.createServer()
//(De-)Serialization for clients
server.serializeClient(function(client, done) {
return done(null, client.clientId)
})
server.deserializeClient(function(id, done) {
db.collection('clients').find({clientId: id}, function(err, client) {
if (err) return done(err)
return done(null, client)
})
})
//Register grant (used to issue authorization codes)
server.grant(oauth2orize.grant.code(function(client, redirectURI, user, ares, done) {
var code = utils.uid(16)
var codeHash = crypto.createHash('sha1').update(code).digest('hex')
db.collection('authorizationCodes').save({code: codeHash, clientId: client._id, redirectURI: redirectURI, userId: user.username}, function(err) {
if (err) return done(err)
done(null, code)
})
}))
//Used to exchange authorization codes for access token
server.exchange(oauth2orize.exchange.code(function (client, code, redirectURI, done) {
db.collection('authorizationCodes').findOne({code: code}, function (err, authCode) {
if (err) return done(err)
if (!authCode) return done(null, false)
if (client.clientId !== authCode.clientId) return done(null, false)
if (redirectURI !== authCode.redirectURI) return done(null, false)
db.collection('authorizationCodes').remove({code: code}, function(err) {
if(err) return done(err)
var token = utils.uid(256)
var refreshToken = utils.uid(256)
var tokenHash = crypto.createHash('sha1').update(token).digest('hex')
var refreshTokenHash = crypto.createHash('sha1').update(refreshToken).digest('hex')
var expirationDate = new Date(new Date().getTime() + (3600 * 1000))
db.collection('accessTokens').save({token: tokenHash, expirationDate: expirationDate, userId: authCode.userId, clientId: authCode.clientId}, function(err) {
if (err) return done(err)
db.collection('refreshTokens').save({refreshToken: refreshTokenHash, clientId: authCode.clientId, userId: authCode.userId}, function (err) {
if (err) return done(err)
done(null, token, refreshToken, {expires_in: expirationDate})
})
})
})
})
}))
//Refresh Token
server.exchange(oauth2orize.exchange.refreshToken(function (client, refreshToken, scope, done) {
var refreshTokenHash = crypto.createHash('sha1').update(refreshToken).digest('hex')
db.collection('refreshTokens').findOne({refreshToken: refreshTokenHash}, function (err, token) {
if (err) return done(err)
if (!token) return done(null, false)
if (client.clientId !== token.clientId) return done(null, false)
var newAccessToken = utils.uid(256)
var accessTokenHash = crypto.createHash('sha1').update(newAccessToken).digest('hex')
var expirationDate = new Date(new Date().getTime() + (3600 * 1000))
db.collection('accessTokens').update({userId: token.userId}, {$set: {token: accessTokenHash, scope: scope, expirationDate: expirationDate}}, function (err) {
if (err) return done(err)
done(null, newAccessToken, refreshToken, {expires_in: expirationDate})
})
})
}))
// user authorization endpoint
exports.authorization = [
function(req, res, next) {
if (req.user) next()
else res.redirect('/login')
},
server.authorization(function(clientId, redirectURI, done) {
db.collection('clients').findOne({clientId: clientId}, function(err, client) {
if (err) return done(err)
// WARNING: For security purposes, it is highly advisable to check that
// redirectURI provided by the client matches one registered with
// the server. For simplicity, this example does not. You have
// been warned.
return done(null, client, redirectURI)
})
}),
function(req, res) {
res.render('decision', { transactionID: req.oauth2.transactionID, user: req.user, client: req.oauth2.client })
}
]
// user decision endpoint
exports.decision = [
function(req, res, next) {
if (req.user) next()
else res.redirect('/login')
},
server.decision()
]
// token endpoint
exports.token = [
passport.authenticate(['clientBasic', 'clientPassword'], { session: false }),
server.token(),
server.errorHandler()
]