{
"host": "localhost",
"port": 3030,
"public": "../public/",
"paginate": {
"default": 10,
"max": 50
},
"authentication": {
"secret": "SOME-KEY",
"strategies": [
"local",
"jwt"
],
"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"
}
},
"postgres": "postgresql://dbadmin:mydb@localhost:5432/mydb_table"
}
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6ImFjY2VzcyJ9.eyJ1c2VySWQiOiIzMzAyM2I3ZS1iOTZhLTRhODQtYjJjOS01ZTc4OWQxMmFhMzUiLCJpYXQiOjE1NjAxNjMyOTQsImV4cCI6MTU2MDI0OTY5NCwiYXVkIjoiaHR0cHM6Ly95b3VyZG9tYWluLmNvbSIsImlzcyI6ImZlYXRoZXJzIiwic3ViIjoiYW5vbnltb3VzIiwianRpIjoiNmRkYzc2N2MtODFkMC00OTYzLTk3MDItNjY3Nzc3YTVkNDVlIn0.DecMVpm0mYeYa8ckco9fHg1rLieCzB3CBTS8XMKYUJk"
}
Should return a user object, eg.
{
"id": "33023b7e-b96a-4a84-b2c9-5e789d12aa35",
"first_name": "Alex",
"last_name": "D",
"email": "[email protected]",
"is_verified": false
}
Returns an empty object {}
"@feathersjs/authentication": "2.1.16",
"@feathersjs/authentication-jwt": "^2.0.7",
"@feathersjs/authentication-local": "^1.2.7",
"@feathersjs/configuration": "^2.0.4",
"@feathersjs/errors": "^3.3.4",
"@feathersjs/express": "^1.2.7",
"@feathersjs/feathers": "^3.2.3",
"engines": {
"node": "^12.0.0",
"yarn": ">= 0.18.0"
},
Tell us about the applicable parts of your setup.
NodeJS version:
12.0.0
Operating System:
MacOS 10.13.6
Decoded token:
{
"userId": "33023b7e-b96a-4a84-b2c9-5e789d12aa35",
"iat": 1560163294,
"exp": 1560249694,
"aud": "https://yourdomain.com",
"iss": "feathers",
"sub": "anonymous",
"jti": "6ddc767c-81d0-4963-9702-667777a5d45e"
}
The authenticate('jwt') hook needs to do a second get request on the users service without any parameters in order to retrieve the actual object to set as params.user. So you will see two, one without first (it is an internal call because params.provider will be undefined) and then a second get with params.user set.
The
authenticate('jwt')hook needs to do a secondgetrequest on the users service without any parameters in order to retrieve the actual object to set asparams.user. So you will see two, one without first (it is an internal call because params.provider will beundefined) and then a secondgetwithparams.userset.
Solved it by changing userFillter hook to
module.exports = function (options = {}) {
return async context => {
context.result = context.params.user;
return context;
};
};
Any idea why it does NOT work if
context.result = context.params.user || {};
OR
context.result = _.get(context.params, 'user', {});
very strange
Your example token does not include the userId as the payload (check at jwt.io that it does). This is usually the case when the authentication module is not configured properly.
@daffl @fireflypie I'm experiencing the same problem with postgres. I've read over several old issues and have had no success with this. Could you elaborate on properly configuring the authentication module? What was the solution?
my decoded jwt:
{
"iat": 1588539863,
"exp": 1588626263,
"aud": "https://yourdomain.com",
"iss": "feathers",
"sub": "26",
"jti": "ecfd0e55-2b27-4834-97fd-cff19ea9a524"
}
sub is the id of the user I'm logged in as.
The hook
module.exports = (options = {}) => {
return async context => {
context.result = context.params.user;
return context;
};
};
there is never a context.params.user object and result is always undefined
Please create a new issue ideally with a link to a complete minimal repository to reproduce the problem.
@daffl @fireflypie I'm experiencing the same problem with postgres. I've read over several old issues and have had no success with this. Could you elaborate on properly configuring the authentication module? What was the solution?
my decoded jwt:
{ "iat": 1588539863, "exp": 1588626263, "aud": "https://yourdomain.com", "iss": "feathers", "sub": "26", "jti": "ecfd0e55-2b27-4834-97fd-cff19ea9a524" }sub is the id of the user I'm logged in as.
The hook
module.exports = (options = {}) => { return async context => { context.result = context.params.user; return context; }; };there is never a context.params.user object and result is always undefined
I had a similar issue and I was able to fix it by bringing the authenticate hook before my processProperty hook as shown below.
I think this is because each hook in the array is processed from left to right, so in this case, the processProperty hook needs access to the authenticated user, so it needs to come after the authenticate hook has been processed.
module.exports = {
before: {
...
create: [authenticate('jwt'), processProperty()],
...
}
}
The
authenticate('jwt')hook needs to do a secondgetrequest on the users service without any parameters in order to retrieve the actual object to set asparams.user. So you will see two, one without first (it is an internal call because params.provider will beundefined) and then a secondgetwithparams.userset.
I've spent like 4 hours or more until I've read this explanation and now I understand why I've always was getting errors when trying to access any property from the context.params.user object (like theid , for instance) from my own custom "before get hook". Since the hook gets fired two times, the first time with authenticate ('jwt') as you pointed the user object is not still there, the second and other ones the context.params.user object is there.
So, I've solved the problem checking for the user property from thecontext.params object before trying to use it.
Thanks for your explanation!
If you are using middleware to call a service, this could be the problem
My problem was
service.find({query,params:req.feathers}).then(...).
in this case context.params.user is undefined
But what worked for me is
service.find({query,...req.feathers}).then(...)
Most helpful comment
The
authenticate('jwt')hook needs to do a secondgetrequest on the users service without any parameters in order to retrieve the actual object to set asparams.user. So you will see two, one without first (it is an internal call because params.provider will beundefined) and then a secondgetwithparams.userset.