@feathersjs/authentication-oauth1
A Feathers OAuth1 authentication strategy
Installation
npm install @feathersjs/authentication-oauth1 --save
Note: This is only compatibile with feathers-authentication@1.x
and above.
Documentation
Please refer to the @feathersjs/authentication-oauth1 documentation for more details.
Supported Strategies
There aren't a ton of OAuth1 strategies anymore as most have moved to OAuth2, however this will work for any Passport OAuth1 strategy. Most notably Twitter.
API
This module contains 2 core pieces:
- The main entry function
- The
Verifier
class
Main Initialization
In most cases initializing the @feathersjs/authentication-oauth1
module is as simple as doing this:
const session = require('express-session');
const TwitterStrategy = require('passport-twitter').Strategy;
app.use(session({ secret: 'super secret', resave: true, saveUninitialized: true }));
app.configure(authentication(settings));
app.configure(oauth1({
name: 'twitter',
Strategy: TwitterStrategy,
consumerKey: '<your consumer key>',
consumerSecret: '<your consumer secret>'
}));
This will set up session middleware and authentication pulling from your global auth
object in your config file. It will also mix in the following defaults, which can be customized.
Default Options
{
idField: '<provider>Id',
path: '/auth/<provider>',
callbackPath: '/auth/<provider>/callback',
callbackURL: 'http(s)://hostame[:port]/auth/<provider>/callback',
entity: 'user',
service: 'users',
passReqToCallback: true,
session: true
handler: function,
formatter: function,
Verifier: Verifier
}
Additional passport strategy options can be provided based on the OAuth1 strategy you are configuring.
Verifier
This is the verification class that handles the OAuth1 verification by looking up the entity (normally a user
) on a given service and either creates or updates the entity and returns them. It has the following methods that can all be overridden. All methods return a promise except verify
, which has the exact same signature as passport-oauth1.
{
constructor(app, options)
_updateEntity(entity)
_createEntity(entity)
_normalizeResult(result)
verify(req, accessToken, refreshToken, profile, done)
}
Customizing the Verifier
The Verifier
class can be extended so that you customize it's behavior without having to rewrite and test a totally custom local Passport implementation. Although that is always an option if you don't want use this plugin.
An example of customizing the Verifier:
import oauth1, { Verifier } from '@feathersjs/authentication-oauth1';
class CustomVerifier extends Verifier {
verify(req, accessToken, refreshToken, profile, done) {
done(null, user);
}
}
app.configure(oauth1({
name: 'twitter'
Strategy: TwitterStrategy,
consumerKey: '<your consumer key>',
consumerSecret: '<your consumer secret>',
Verifier: CustomVerifier
}));
Customizing The OAuth Response
Whenever you authenticate with an OAuth1 provider such as Twitter, the provider sends back an accessToken
, refreshToken
, and a profile
that contains the authenticated entity's information based on the OAuth1 scopes
you have requested and been granted.
By default the Verifier
takes everything returned by the provider and attaches it to the entity
(ie. the user object) under the provider name. You will likely want to customize the data that is returned. This can be done by adding a before
hook to both the update
and create
service methods on your entity
's service.
app.configure(oauth1({
name: 'twitter',
entity: 'user',
service: 'users',
Strategy,
consumerKey: '<your consumer key>',
consumerSecret: '<your consumer secret>'
}));
function customizeTwitterProfile() {
return function(hook) {
console.log('Customizing Twitter Profile');
if (hook.data.twitter) {
hook.data.email = hook.data.twitter.email;
}
if (hook.params.oauth) {
}
if (hook.params.oauth.provider === 'twitter') {
}
return Promise.resolve(hook);
};
}
app.service('users').hooks({
before: {
create: [customizeTwitterProfile()],
update: [customizeTwitterProfile()]
}
});
Complete Example
Here's a basic example of a Feathers server that uses @feathersjs/authentication-oauth1
. You can see a fully working example in the example/ directory.
Note: You must setup some session middleware. OAuth1 strategies rely on sessions in order to authenticate.
const feathers = require('feathers');
const rest = require('feathers-rest');
const hooks = require('feathers-hooks');
const memory = require('feathers-memory');
const bodyParser = require('body-parser');
const session = require('express-session');
const TwitterStrategy = require('passport-twitter').Strategy;
const errorHandler = require('feathers-errors/handler');
const auth = require('feathers-authentication');
const oauth1 = require('@feathersjs/authentication-oauth1');
const app = feathers()
.configure(rest())
.use(bodyParser.json())
.use(bodyParser.urlencoded({ extended: true }))
.use(session({ secret: 'super secret', resave: true, saveUninitialized: true }))
.configure(auth({ secret: 'super secret' }))
.configure(oauth1({
name: 'twitter',
Strategy: TwitterStrategy,
consumerKey: '<your consumer key>',
consumerSecret: '<your consumer secret>'
}))
.use('/users', memory())
.use(errorHandler());
app.listen(3030);
console.log('Feathers app started on 127.0.0.1:3030');
License
Copyright (c) 2016
Licensed under the MIT license.