-
Notifications
You must be signed in to change notification settings - Fork 526
[Auth]: Guide for using custom passport strategy #787
Comments
It's actually quite easy to use a passport strategy with Feathers. You don't need to wrap it up like we do with our authentication plugins (ie. This is how you can use a vanilla API key Passport Strategy with Feathers: const apiKeyStrategy = new LocalAPIKeyStrategy({
entity: 'org' // if you wanted to map the returned entity to a different name
},
function(apikey, done) {
const query = { apikey };
app.service('users').find({ query }).then((err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, false); }
// this will expose the user as req.user in middleware or hook.params.user
// in Feathers hooks.
return done(null, user);
});
}
);
app.configure(authentication());
app.passport.use('localapikey', apiKeyStrategy);
// in your hooks
app.service('users').hooks({
before: {
all: [auth.hooks.authenticate(['localapikey'])]
}
}); Note: This token strategy is great for basic APIs but it won't work with the Feathers client directly. You would need to exchange the API key for a JWT and then the feathers JWT access token is used to fetch subsequent API calls. In order to do that you would have to modify the example above to be like this: const apiKeyStrategy = new LocalAPIKeyStrategy(
function(apikey, done) {
const query = { apikey };
app.service('users').find({ query }).then((err, user) => {
if (err) { return done(err); }
if (!user) { return done(null, false); }
return done(null, user);
});
}
);
app.configure(authentication())
.configure(jwt());
app.passport.use('localapikey', apiKeyStrategy);
// in your hooks
app.service('authentication').hooks({
before: {
all: [auth.hooks.authenticate(['localapikey'])]
}
});
app.service('users').hooks({
before: {
all: [auth.hooks.authenticate(['jwt'])]
}
}); Usually instead of an API key we recommend using If you wanted to set the app.service('users').hooks({
before: {
all: [
auth.hooks.authenticate(['localapikey'], { entity: 'custom' } )]
}
}); |
I think an example with Use CaseWhenever a new user lands on the website authenticate them anonymously by creating a new user in the database with the role 'customer'. // authService.js
import auth from 'feathers-authentication';
import jwt from 'feathers-authentication-jwt';
import local from 'feathers-authentication-local';
import anonymous from './anonymous';
import { server } from 'config';
export default () => {
return function() {
this.configure(auth(server.auth));
this.configure(jwt());
this.configure(local(server.auth.local));
this.configure(anonymous(server.auth.anonymous));
};
}; // anonymous.js
import Strategy from 'passport-custom';
export default opts => {
return function() {
const verifier = async (req, done) => {
const role = await this.service(opts.roleService).find({
query: {
name: 'customer',
$limit: 1
}
});
const user = await this.service(opts.userService).create({
roleId: role[0].id
});
const jwtPayloadAdditions = {
userId: user.id
}
return done(null, user, jwtPayloadAdditions);
};
this.passport.use('anonymous', new Strategy(verifier));
};
}; |
This has been added in https://docs.feathersjs.com/guides/auth/recipe.custom-auth-strategy.html |
There is now a feathers-authentication-custom strategy which makes this a little easier: https://github.com/feathersjs-ecosystem/feathers-authentication-custom |
Maybe someone would be interested in updating the guide to use this. |
I was planning on updating the guide as well :) |
In some cases you there might not be a passport strategy that fits the OAuth1, OAuth2 or Local auth mold, so you may need to create a custom passport strategy or wrap an existing passport strategy so that it has a similar interface as the Feathers auth plugins.
Todo
The text was updated successfully, but these errors were encountered: