Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom auth strategy #1553

Open
PowerMogli opened this issue Sep 9, 2019 · 13 comments
Open

Custom auth strategy #1553

PowerMogli opened this issue Sep 9, 2019 · 13 comments

Comments

@PowerMogli
Copy link

We are trying to migrate to v4. But now we are failing because we have no clue how to setup a custom auth (api-key) strategy. In v3 we registered our custom api-key strategy at passport like this:

this.passport.use('apikey', new Strategy(verifier));
// and
app.configure(apikey({ header: config.apiKey.header }));

Is there any documentation how to setup a custom (api-key) authentication strategy?

@ivankostic85
Copy link

ivankostic85 commented Sep 14, 2019

Hi, custom apiKey strategy is only thing I have successfully set up after migrating to v4. Oauth still not working for me.

authentication.js

const { LocalStrategy } = require('@feathersjs/authentication-local');
const { expressOauth } = require('@feathersjs/authentication-oauth');
const { NotAuthenticated } = require('@feathersjs/errors');

class ApiKeyStrategy extends AuthenticationBaseStrategy {
  constructor (headerField = 'x-api-key') {
    super();
    this.headerField = headerField;
  }

  authenticate(authRequest, params) {
    const { apiKey } = authRequest;

    const match = this.app.get('allowed-tokens').includes(apiKey);
    
    if (!match) {
      throw new NotAuthenticated('Invalid API key');
    }
    
    // To add a user look it up from the service
    // const [ user ] = await this.app.service('users').get({ ...params, query: userQuery })
    
    return {
      apiKey: true
      // user
    };
  }
  
  parse (req) {
    const header = req.headers[this.headerField];
    
    if (header) {
      return {
        strategy: this.name,
        apiKey: header
      };
    }
    
    return null;
  }
}

module.exports = app => {
  const authentication = new AuthenticationService(app);

  authentication.register('jwt', new JWTStrategy());
  authentication.register('local', new LocalStrategy());
  authentication.register('apiKey', new ApiKeyStrategy());

  app.use('/authentication', authentication);
  app.configure(expressOauth());
};```

./hooks/allowApiKey.js

/* eslint-disable require-atomic-updates */
module.exports = function (options = {}) { // eslint-disable-line no-unused-vars
return async context => {
const { params } = context;

  if(params.provider && !params.authentication && params.headers && params.headers['x-api-key']) {
    
    context.params = {
      ...params,
      authentication: {
        strategy: 'apiKey',
        apiKey: params.headers['x-api-key']
      }
    }
  }
  return context;
};

};

 
Now in every service you want to access with this strategy you must add this hook and auth..
/services/users/users.hook.js

```const allowApiKey = require('../../hooks/allowApiKey');

module.exports = {
  before: {
    all: [ allowApiKey(), authenticate('jwt', 'apiKey') ],
...```

@ivankostic85
Copy link

In my example header key is "x-api-key" and I have array of tokens in config called allowed-tokens and this part
const match = this.app.get('allowed-tokens').includes(apiKey);
can be simple
const match = apiKey === 'yourxxxsecret'

Hope I help you and if you have working oauth google and facebook strategies, please help me :)

@bartduisters
Copy link
Contributor

Hope I help you and if you have working oauth google and facebook strategies, please help me :)

Facebook: https://docs.feathersjs.com/cookbook/authentication/facebook.html
Google (not yet merged): https://github.com/feathersjs/docs/blob/495f82121ee22a5eca1f82bfa64c5c8e2bc1e518/cookbook/authentication/google.md

@ivankostic85
Copy link

Thanks @bartduisters I have managed to solve issues with Google and Facebook providers. In your Google cookbook example there are no getProfil method. I can send you my if you want to checkout

@bartduisters
Copy link
Contributor

The .getProfile() method is not necessary if all the information you want is the information used in the recipe.

I think the issue can be closed since the OP has an answer + you have an answer.

@MarcGodard
Copy link
Contributor

This seems to be working for me, but haven't fully tested yet (thanks)... now I just need to figure out how to add a custom Verifier for local....

In V3: app.configure(local({ Verifier: CustomVerifier })) and adding it in V4 here: authentication.register('local', new LocalStrategy({ Verifier: CustomVerifier })) doesn't work :(

@daffl
Copy link
Member

daffl commented Oct 6, 2019

There are no more verifiers in v4. Strategies are now customized by extending them as is documented in

@cupcakearmy
Copy link

Hi,
I'm new to the whole feathers world. I really like the approach you guys are taking :)
Is there any way of doing custom authentication? Let's say for example I want to have a custom jwt secret for each user. What would be the approach you'd recommend?

@MarcGodard
Copy link
Contributor

@cupcakearmy See this: #1601

@dmitry-tuzenkov
Copy link

Hey @PowerMogli ,

try this one https://www.npmjs.com/package/@thesinding/authentication-api-key

Cheers!

@jiangts
Copy link

jiangts commented Apr 28, 2020

In the AuthenticationBaseStrategy that @ikakosta posted, does it use the parse method at all? I implemented it and it seems that method is never called... (only the hook matters).

Just curious. @daffl the docs here https://docs.feathersjs.com/api/authentication/strategy.html#parse-req-res aren't super clear on when parse is ever called / other usage patterns.

@daffl
Copy link
Member

daffl commented Apr 28, 2020

Can probably be improved by pointing to the parseStrategies and authStrategies configuration option where the name of the strategy you want to use has to be added.

@jiangts
Copy link

jiangts commented Apr 28, 2020

Yep! I just figured it out. It just needs to be added to the authStrategies config!
Probably the anonymous auth guide should also be updated to add "anonymous" to authStrategies rather than using a hook...

Thanks for the fast reply!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants