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

authentication-jwt functional example #657

Closed
HDCARDENAS2 opened this Issue Mar 22, 2018 · 2 comments

Comments

Projects
None yet
3 participants
@HDCARDENAS2
Copy link

HDCARDENAS2 commented Mar 22, 2018

I have a problem to understand how JWT validation works in the creation and authentication parts.
I have not been able to make a functional project with the examples of the web, the documentation has been difficult for me because I am new and I am learning the framework, and the documentation only includes small code, and I do not know what file to belong to. put in the project, I have been looking for 2 days in several places, even in the problems, and I could not find a functional example, with which you can learn to know how to do it.

help me with a functional example, where I can identify with user and password, it is not necessary to exist in the database, I will validate it with web service, this will retrieve the user data, in case it is correct to create the TOKEN, then return it, and be able to make a GET request to a model, but with authentication

This could be the last thing for me and for other people who are just learning.
https://docs.feathersjs.com/guides/chat/authentication.html

my code

app.js

const path = require('path');
const favicon = require('serve-favicon');
const compress = require('compression');
const cors = require('cors');
const helmet = require('helmet');
const logger = require('winston');

const feathers = require('@feathersjs/feathers');
const configuration = require('@feathersjs/configuration');
const express = require('@feathersjs/express');
const socketio = require('@feathersjs/socketio');


const middleware = require('./middleware');
const services = require('./services');
const appHooks = require('./app.hooks');
const channels = require('./channels');

const authentication = require('./authentication');

const app = express(feathers());

// Load app configuration
app.configure(configuration());
// Enable CORS, security, compression, favicon and body parsing
app.use(cors());
app.use(helmet());
app.use(compress());
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(favicon(path.join(app.get('public'), 'favicon.ico')));
// Host the public folder
app.use('/', express.static(app.get('public')));

// Set up Plugins and providers
app.configure(express.rest());
app.configure(socketio());

// Configure other middleware (see `middleware/index.js`)
app.configure(middleware);
app.configure(authentication);
// Set up our services (see `services/index.js`)
app.configure(services);
// Set up event channels (see channels.js)
app.configure(channels);

// Configure a middleware for 404s and the error handler
app.use(express.notFound());
app.use(express.errorHandler({ logger }));

app.hooks(appHooks);

module.exports = app;

authentication.js

const authentication = require('@feathersjs/authentication');
const jwt = require('@feathersjs/authentication-jwt');
const local = require('@feathersjs/authentication-local');


module.exports = function (app) {
  const config = app.get('authentication');

  // Set up authentication with the secret
  app.configure(authentication(config));
  app.configure(jwt());
  app.configure(local());

  // The `authentication` service is used to create a JWT.
  // The before `create` hook registers strategies that can be used
  // to create a new valid JWT (e.g. local or oauth2)
  app.service('authentication').hooks({
    before: {
      create: [
        authentication.hooks.authenticate(config.strategies)
      ],
      remove: [
        authentication.hooks.authenticate('jwt')
      ]
    }
  });
};
`
config\default.json
`{
  "host": "localhost",
  "port": 3030,
  "public": "../public/",
  "paginate": {
    "default": 10,
    "max": 50
  },
  "authentication": {
    "secret": "ad2d69517a0c5e5faf01cacf863877571d60eb02f98e2de67be5b8dce7292135b3978e8a99bdf4e12bdb7c1d2d751aa03841c256462ad35592eb6b1120ebbaf1c720a3f688316d48de1e3a77dcc1f7d7cfc38490f4ef95f0011cedd2b0e6209d172702badcb811add875cdd583afb99a0f8c0624546140330d86eb2980b75ebcc150f7a304a05eed4e5c74db48ae67dfe58befdec93ec77eae9d1d4bb4aa55cfa6e2cb4d390e1850892a7906edbc51eeacd282951a0d50a6d8c195baeb5cfd88204e577b668b158f4e1d8e2cebd8392fe8ce20c3b1a7617ad98a2ed7f5d6c4ec63372b8370d9c1b1c8b56e67cb5f41333861aed164338a93791b64fd78fb2e80",
    "strategies": [
      "jwt",
      "local"
    ],
    "path": "/authentication",
    "service": "users",
    "jwt": {
      "header": {
        "typ": "access"
      },
      "audience": "https://yourdomain.com",
      "subject": "anonymous",
      "issuer": "feathers",
      "algorithm": "HS256",
      "expiresIn": "1d"
    },
    "local": {
      "entity": "user",
      "usernameField": "email",
      "passwordField": "password"
    }
  }
}

src\services\users\users.service.js

// Initializes the users service on path 
const createService = require('./users.class.js');
const hooks = require('./users.hooks');

module.exports = function (app) {
  
  const paginate = app.get('paginate');

  const options = {
    name: 'users',
    paginate
  };

  // Initialize our service with any options it requires
  app.use('/users', createService(options));

  // Get our initialized service so that we can register hooks and filters
  const service = app.service('users');

  service.hooks(hooks);
};

src\services\users\users.hooks.js

const { authenticate } = require('@feathersjs/authentication').hooks;

const {
  hashPassword, protect
} = require('@feathersjs/authentication-local').hooks;

module.exports = {
  before: {
    all: [],
    find: [ authenticate('jwt') ],
    get: [ authenticate('jwt') ],
    create: [ hashPassword() ],
    update: [ hashPassword(),  authenticate('jwt') ],
    patch: [ hashPassword(),  authenticate('jwt') ],
    remove: [ authenticate('jwt') ]
  },

  after: {
    all: [ 
      // Make sure the password field is never sent to the client
      // Always must be the last hook
      protect('password')
    ],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  },

  error: {
    all: [],
    find: [],
    get: [],
    create: [],
    update: [],
    patch: [],
    remove: []
  }
};

src\services\users\users.class.js

/* eslint-disable no-unused-vars */
class Service {
  constructor (options) {
    this.options = options || {};
  }

  async find (params) {
    return [];
  }

  async get (id, params) {
    return {
      id, text: `A new message with ID: ${id}!`
    };
  }

  async create (data, params) {
    if (Array.isArray(data)) {
      return await Promise.all(data.map(current => this.create(current)));
    }
    return data;
  }

  async update (id, data, params) {
    return data;
  }

  async patch (id, data, params) {
    return data;
  }

  async remove (id, params) {
    return { id };
  }
}

module.exports = function (options) {
  return new Service(options);
};

module.exports.Service = Service;
@daffl

This comment has been minimized.

Copy link
Member

daffl commented Mar 25, 2018

The chat guide will use Feathers and its authentication client on the frontend so you don't really have to be familiar with the specifics of JWT.

A more detailed explanation how to use the JWT can be found in the REST API client usage documentation.

I added a note in the authentication that links to that paragraph.

@MarcGodard

This comment has been minimized.

Copy link

MarcGodard commented Dec 30, 2018

I have a question about this example. I am doing the same app.service('authentication').hooks({ for my custom auth stuff, but I always get error: Unhandled Rejection at: Promise after the app.service('authentication').remove() call.

Is this something I should fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.