-
Notifications
You must be signed in to change notification settings - Fork 117
JWT Authentication setup failing #411
Comments
@zusamann, please post the version numbers of each of the imported modules. |
Latest ones on NPM I think, since I just did a npm i -S ......
|
If you are using |
But as you can see above @daffl I did two attempts, with and without |
Ok here I am using import feathers from 'feathers';
import rest from 'feathers-rest';
import bodyParser from 'body-parser';
import auth from 'feathers-authentication';
import jwt from 'feathers-authentication-jwt';
import sequelize from 'feathers-sequelize';
const db = require('./models');
const init = () => {
const app = feathers();
app.configure(rest());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.configure(auth({ secret: 'my-secret' }));
app.configure(jwt());
Object.keys(db.sequelize.models)
.map(key =>
app.use(`/rest/${key}`, sequelize({
Model: db[key],
paginate: {
default: 5,
max: 25
}
}))
);
app.listen(3030);
};
export const run = () => init(); D:\code\playground\core-playground\feathers\node_modules\feathers-authentication-jwt\lib\verifier.js:32
throw new Error('options.service does not exist.\n\tMake sure you are passing a valid service path or service instance and it is initialized before feathers-authentication-jwt.');
^
Error: options.service does not exist.
Make sure you are passing a valid service path or service instance and it is initialized before feathers-authentication-jwt. |
@zusamann, check out the default options for the jwt plugin here: https://github.com/feathersjs/feathers-authentication-jwt#default-options. You probably need to fix the |
Yes you are right @marshallswain this error is not thrown anymore. I had to add the following: import memory from 'feathers-memory';
// ...
// ...
app.use('/users', memory()); Now I was looking to finally use the authentication on all of my endpoints which I'm generating procedurally like so: Object.keys(db.sequelize.models).map(key =>app.use(`/rest/${key}`, sequelize({ Model: db[key] }))); So I added the following: app.service('authentication').hooks({
before: {
all: [
auth.hooks.authenticate('jwt')
]
}
}); But it is generating the following error:
|
@zusamann you probably just need to install the hooks plugin: https://github.com/feathersjs/feathers-hooks#quick-start |
But not import it anywhere? |
Use the quick start I just linked. |
Right again @marshallswain, had to add the following to the code: import hooks from 'feathers-hooks';
// ...
// ...
app.configure(hooks()); And modify the service creation so the hooks are added over the keys.map. Object.keys(db.sequelize.models)
.map(key =>
app.use(`/rest/${key}`, sequelize({
Model: db[key],
paginate: {
default: 5,
max: 25
}
}))
.hooks({
before: {
all: [
auth.hooks.authenticate(['jwt'])
]
}
})
); Thank you so much for your help. I was wondering if the docs could be updated to reflect some of the nuances covered above. Of placing a users service and configuring hooks, etc. |
The Auk docs will contain all of the information for [email protected]. Just out of curiosity, why did you decide to install feathers-authentication-jwt? How did you discover it? I ask because the current release of feathers-authentication on npm already includes that functionality. We decided to implement auth plugins in the upcoming release (which you've just upgraded to using) |
I see. We have big docs updates underway as the final part of the Auk release, so the confusion will disappear, shortly. |
Glad to hear that, do you think the already out releases of Auk like the new authentication plugin are stable enough to use in production? Cause I'm really looking forward to using all of what I can find. |
|
Great! Looking forward to it. |
In the meantime, using [email protected], you'll probably want to familiarize yourself with the old authentication hooks. Some might work, but others you might have to modify. https://github.com/feathersjs/feathers-legacy-authentication-hooks |
Back again, having trouble setting up the client side usage. /**
server.js
"feathers": "^2.0.3",
"feathers-authentication": "^1.0.2",
"feathers-authentication-jwt": "^0.3.1",
**/
import feathers from 'feathers';
import rest from 'feathers-rest';
import bodyParser from 'body-parser';
import auth from 'feathers-authentication';
import jwt from 'feathers-authentication-jwt';
import hooks from 'feathers-hooks';
import errorHandler from 'feathers-errors/handler';
import memory from 'feathers-memory';
import sequelize from 'feathers-sequelize';
import cors from 'cors';
import socketio from 'feathers-socketio';
const db = require('./models');
const init = () => {
const app = feathers();
app.use(cors());
app.configure(socketio({
wsEngine: 'uws'
}));
app.configure(rest());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.configure(hooks());
app.configure(auth({ secret: 'secret' }));
app.configure(jwt());
app.use('/users', memory());
Object.keys(db.sequelize.models)
.map(key => {
app.use(`/db/${key}`, sequelize({
Model: db[key],
paginate: {
default: 10,
max: 25
}
}));
app.service(`/db/${key}`).hooks({
before: {
all: [
auth.hooks.authenticate(['jwt'])
]
}
});
});
app.use(errorHandler());
app.listen(3030);
};
export const run = () => init(); /**
client.js
"feathers-client": "^1.9.0",
**/
import feathers from 'feathers-client';
// import io from 'socket.io-client';
import axios from 'axios';
const host = 'http://localhost:3030';
const client = feathers()
// .configure(feathers.socketio(io(host)))
.configure(feathers.rest(host).axios(axios)) // tried both clients, explained below
.configure(feathers.hooks())
.configure(feathers.authentication({
storage: window.localStorage
}));
export default client; /**
App.js (client side)
**/
class App extends Component {
constructor() {
super()
this.state = { films: [] }
client.authenticate({
type: 'token',
endpoint: '/authentication' // without this the default post is to /auth/token, a bit confusing
})
.then(res => {
console.log(res) // get a token with rest client, nothing comes with io client
window.localStorage
.setItem('feathers-jwt', res.accessToken); // tried without this first, that didnt work either
client.service('/db/film').get(1).then(console.log) // errors out, 401 unautho...
})
.catch(rej => console.log(rej))
//... So having trouble setting the fetched token in rest client, and with io client not getting any token at all. Both resulting in 401s. My thinking is it might be due to using incompatible server and client side auth libs. |
On further exploration, this works on with the rest client, but doesn't with the io client. Don't even get an error. Which tells me there needs to be done something entirely different with the io client. /**
App.js (client side)
**/
class App extends Component {
constructor() {
super()
this.state = { films: [] }
client.authenticate({
type: 'token',
endpoint: '/authentication'
})
.then(res => {
client.set('token', res.accessToken)
client.service('/db/film').get(1).then(console.log)
})
.catch(rej => console.log(rej))
//... |
@zusamann Looks like you're still using the old version of the auth client. You can upgrade by importing the new client plugin: import auth from 'feathers-authentication-client'
...
.configure(auth({
storage: window.localStorage
})); |
I'm actually not using the individual clients. Rather |
Nah. You can keep everything else the same. Just change the auth plugin part. |
Ok will try that and revert |
/**
"feathers-authentication-client": "^0.1.7",
"feathers-client": "^1.9.0",
**/
// client.js
import feathers from 'feathers-client';
import auth from 'feathers-authentication-client';
// import io from 'socket.io-client';
import axios from 'axios';
const host = 'http://localhost:3030';
const client = feathers()
// .configure(feathers.socketio(io(host)))
.configure(feathers.rest(host).axios(axios))
.configure(feathers.hooks())
.configure(auth({
storage: window.localStorage
}));
export default client;
// App.js
class App extends Component {
constructor() {
super()
client.authenticate({
type: 'token',
endpoint: '/authentication'
})
.then(console.log)
.catch(console.error)
}
render() {
// ... Getting this error in my browser console twice.
|
The API has changed. You now need to specify the
A shortcut to the above would be to simply call client.authenticate() If there is a token in storage, it will attempt to login. If not, it will return an error that no token was found. |
Actually I tried with all the various combinations of params. And just now I tried the below again. client.authenticate()
.then(console.log)
.catch(console.error) Tried setting the token manually too client.authenticate()
.then(res => window.localStorage.setItem('feathers-jwt', res.accessToken))
.catch(console.error) Getting the same error as above on both. |
It's actually erroring out even before the So there must be some thing wrong with this: /**
"feathers-authentication-client": "^0.1.7",
"feathers-client": "^1.9.0",
**/
// client.js
import feathers from 'feathers-client';
import auth from 'feathers-authentication-client';
// import io from 'socket.io-client';
import axios from 'axios';
const host = 'http://localhost:3030';
const client = feathers()
// .configure(feathers.socketio(io(host)))
.configure(feathers.rest(host).axios(axios))
.configure(feathers.hooks())
.configure(auth({
storage: window.localStorage
}));
export default client; |
I thought it was this file: https://github.com/feathersjs/feathers-authentication-client/blob/master/src/passport.js But it's not in that file, directly. Can you trace it down? |
Can you post your code in a repo that I can pull? |
Yes sure, give me few minutes |
@marshallswain here is the code: There are two folders In order to connect with your own db you'll have to change line 15 in let sequelize = new Sequelize('postgres://postgres:password@localhost:5432/dvdrental', databaseOptions); You can alternatively load some completely different db and models as you see fit. |
Were you able to have a go? In any case what would be your suggestion @marshallswain |
Trying this out right now. |
@zusamann I made a PR to your repo. https://github.com/zusamann/feathers-poc/pull/1 Both local and jwt auth should work, now. You'll need to integrate the client, but it should be trivial, now. I didn't import the Postgres database, and just focused on getting auth working. |
@marshallswain sorry but I'm getting the same error on the client side. Can you have a look at the client side code? It's in the
Also didn't really understand the change you made to thee server side code. I mean apart from including the local auth strategy, it seems like you replaced memory with nedb but not much else for jwt auth. The auth was working fine on the server side earlier as well which is why I had closed the issue earlier. But at that point I was simply using POSTMAN, this time I was looking to use the client. Also this change in server.js actually stopped my server from running as the file bootstrap.js expects a function run to work, so not sure how you were running the server. That's a minor point though.
|
@zusamann
I'll take a look later today.
The most important part was registering the hook on the |
@zusamann I think you might have a problem with your environment. I don't get the error you pasted, above. I just submitted another PR where I got auth working. Try removing your node_modules folders on the client and reinstall. It probably shouldn't matter, but I installed modules using Yarn. Here's the PR: https://github.com/zusamann/feathers-poc/pull/2 |
@marshallswain actually I was using |
As for the server change, I was just using |
Ok trying, though to be honest I did a clean install in a separate folder just to be sure when I pushed this code on github.
Okay |
I see. Let me try this. |
Just tried again with a Also just to be clear the server side implementation was working as intended. A call to the open It's just the Do you think it could be a windows issue? Should I try to setup the entire thing in vagrant or something? |
I see you have pushed another PR, let me try with that once. |
Oh, maybe this IS a Windows issue. I literally just opened the |
It could also be an issue with I'll try and set this up without a fancy framework tomorrow and get back to you, because if this is a Thank you and my apologies for the trouble 😅 |
Okay last test result for tonight. Simply doing a const feathers = require('feathers/client');
const hooks = require('feathers-hooks');
const rest = require('feathers-rest/client');
const auth = require('feathers-authentication-client');
const socketio = require('feathers-socketio/client');
const io = require('socket.io-client');
const axios = require('axios');
const localStorage = require('localstorage-memory');
const host = 'http://localhost:3030';
const client = feathers()
.configure(rest(host).axios(axios))
// .configure(socketio(io(host)))
.configure(hooks())
.configure(auth({
storage: localStorage
}));
client.authenticate({
strategy: 'jwt'
})
.then(res => {
console.log(res);
client.service('/db/film').get(1)
.then(console.log)
.catch(console.error)
})
.catch(console.error) |
Ok now I can fully confirm that the above client side error was a webpack/webpack-dev-server#381 I turned off my adblock extension on chrome and the error went away. But haven't been able to solve my problem completely. The intended behavior is the Now the rest client works fine in the above flow but the io client returns a 401, though this only happens for client.authenticate({
strategy: 'jwt'
})
// fine with
.configure(rest(host).axios(axios))
// 401 with
.configure(socketio(io(host))) client.authenticate({
strategy: 'local',
email: '[email protected]',
password: 'feathers'
})
// fine with
.configure(rest(host).axios(axios))
// fine with
.configure(socketio(io(host))) |
Also after this last issue is solved, I was hoping that I could push this entire thing as a documented demo somewhere? Both the client and server side code as a fully realized app. Would like to make more demos of other things like hooks, etc and incorporate them in. |
Slightly off-topic, but I was looking to use For context -- we have an external token management microservice that issues a JWT based |
Had a small discussion with @marshallswain and we concluded that the exact flow that I was trying to achieve was not really a supported strategy in the current auth ecosystem. A hypothetical @marshallswain I think you could probably close this issue in favor of another one detailing out a feature request, would be happy to further the discussion there. |
@shirish87 I think such issues are bound to happen with a release that is not even out yet. But I think it should come out soon, with proper docs, etc. |
@zusamann Totally agree. I was alluding to the convenience of a single-module approach (legacy feathers-authentication) vs. the flexibility of wired-up individual modules. Both approaches have their pros and cons, but the community eventually gravitates to find the right balance :) |
@zusamann if you have an anonymous feature request feel free to open an issue. It actually should work pretty much out of the box. I'll be working on documenting anonymous user auth. Going to close this now as things seem to be fairly sorted for you and this is a pretty lengthy thread. 😄 |
Uh oh!
There was an error while loading. Please reload this page.
Here's my code running on windows 10.
Have also tried this:
Getting this error in both cases:
The text was updated successfully, but these errors were encountered: