fastify / fastify-auth

Run multiple auth functions in Fastify
Other
345 stars 56 forks source link

How to support composited authenication? #41

Closed yunfan closed 5 years ago

yunfan commented 5 years ago

i have some apis needs to be accessed with some higher grants than auth only for ordinary auth check, i have a JWT based identify solution, but for the higher grants i might needs to add a new and strict solution based on JWT

the current support for multiple auth solution of fastify-auth is the relaction of OR, while my needs might need the relation AND

is it possible for you guys to adds a options to toggle that?

like

fastify.post('/api/ordinary', { preHandler: fastify.auth([fastify.jwtcheck, fastify.userpasscheck], {relation: 'or'}) }, handler_ordinary)

fastify.post('/api/strict', { preHandler: fastify.auth([[fastify.jwtcheck, fastify.userpasscheck], fastify.highergrantscheck], {relation: 'and'}) }, handler_ordinary)
Eomm commented 5 years ago

Hi, this could be nice feature to add!

What is necessary is to modify these lines:

https://github.com/fastify/fastify-auth/blob/f6e687837b26b97d4982316cea609789f0ca14e0/fastify-auth.js#L69-L75

in order to manage this new parameter.

That function is always called after the execution of the function in the array:

https://github.com/fastify/fastify-auth/blob/f6e687837b26b97d4982316cea609789f0ca14e0/fastify-auth.js#L62-L66

Would you like to try and send a PR? 💪

yunfan commented 5 years ago

@Eomm i am new to nodejs (from python), but i will try that. it will take servaral days i think.

Eomm commented 5 years ago

This is the best way to learn it 👍🏼

I suggest you to open a draft pr so I can help you step by step if you would like to start it

yunfan commented 5 years ago

@Eomm i am sorry for the delay, after a really busy period, now i could have some time for doing this. now i had some questions on patching the code

Eomm commented 5 years ago

can i use ES6+ features?

We need to support Node.js >= 6 right now, so check https://node.green/ for any doubt. I think Node6 support all ES6 spec, so it shouldn't be problems.

what's the benefit of using nextAuth->onAuth chain?

Instead of a for-each do you mean? Because for loop are sync and we must support also async code and here:

https://github.com/fastify/fastify-auth/blob/f6e687837b26b97d4982316cea609789f0ca14e0/fastify-auth.js#L62

is the user itself that is performing when the auth is complete and we should proceed with the next auth function

yunfan commented 5 years ago

@Eomm by checking https://node.green/ and the supporting goal you mentioned, my understanding is that because async/await were supported 7.10.1. is that right?

Eomm commented 5 years ago

Yes, you have read correctly. node.green is the source of truth

The common thing that can't be used are async or spread operator

(btw async func should be part of the es8 spec released in 2017)

yunfan commented 5 years ago

@Eomm i had problem when running the test after just fork

jyf@jyf:~/devel/repo/fastify-auth$ npm test
npm WARN npm npm does not support Node.js v10.15.2
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8, 9.
npm WARN npm You can find the latest version at https://nodejs.org/

> fastify-auth@0.5.0 test /home/jyf/devel/repo/fastify-auth
> standard && tap -J ./test/*.test.js

/home/jyf/devel/repo/fastify-auth/node_modules/standard/node_modules/standard-engine/index.js:29
  if (!opts.cmd) throw new Error('opts.cmd option is required')
                 ^

Error: opts.cmd option is required
    at new Linter (/home/jyf/devel/repo/fastify-auth/node_modules/standard/node_modules/standard-engine/index.js:29:24)
    at Object.Cli [as cli] (/home/jyf/devel/repo/fastify-auth/node_modules/standard/node_modules/standard-engine/bin/cmd.js:10:18)
    at Object.<anonymous> (/home/jyf/devel/repo/fastify-auth/node_modules/standard/bin/cmd.js:7:30)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:283:19)
npm ERR! Test failed.  See above for more details.
Eomm commented 5 years ago

i had problem when running the test after just fork

I have checked the CI and it is working on master: https://travis-ci.org/fastify/fastify-auth/builds/534402705

What versions of node and npm are you using? I see these unfriendly warnings:

npm WARN npm npm does not support Node.js v10.15.2
npm WARN npm You should probably upgrade to a newer version of node as we
npm WARN npm can't make any promises that npm will work with this version.
npm WARN npm Supported releases of Node.js are the latest release of 4, 6, 7, 8, 9.
npm WARN npm You can find the latest version at https://nodejs.org/
yunfan commented 5 years ago

@Eomm here is my enviroment

jyf@jyf:~$ uname -a
Linux jyf 5.0.0-15-generic #16-Ubuntu SMP Mon May 6 17:41:33 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
jyf@jyf:~$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 19.04
Release:        19.04
Codename:       disco
jyf@jyf:~$ npm -v
5.8.0
jyf@jyf:~$ node -v
v10.15.2
mcollina commented 5 years ago

You have an old version of npm installed. You should install Node.js using https://github.com/nvm-sh/nvm. This will likely solve your issues.

yunfan commented 5 years ago

@mcollina after installed the 12.0 using nvm , i still got problem when using npm i --save here is the last lines from complete log

14502 verbose stack Error: leveldown@2.1.1 install: `prebuild-install || node-gyp rebuild`
14502 verbose stack Exit status 1
14502 verbose stack     at EventEmitter.<anonymous> (/home/jyf/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/npm-lifecycle/index.js:301:16)
14502 verbose stack     at EventEmitter.emit (events.js:196:13)
14502 verbose stack     at ChildProcess.<anonymous> (/home/jyf/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/npm-lifecycle/lib/spawn.js:55:14)
14502 verbose stack     at ChildProcess.emit (events.js:196:13)
14502 verbose stack     at maybeClose (internal/child_process.js:1000:16)
14502 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:267:5)
14503 verbose pkgid leveldown@2.1.1
14504 verbose cwd /home/jyf/devel/repo/fastify-auth
14505 verbose Linux 5.0.0-15-generic
14506 verbose argv "/home/jyf/.nvm/versions/node/v12.0.0/bin/node" "/home/jyf/.nvm/versions/node/v12.0.0/bin/npm" "i" "--save"
14507 verbose node v12.0.0
14508 verbose npm  v6.9.0
14509 error code ELIFECYCLE
14510 error errno 1
14511 error leveldown@2.1.1 install: `prebuild-install || node-gyp rebuild`
14511 error Exit status 1
14512 error Failed at the leveldown@2.1.1 install script.
14512 error This is probably not a problem with npm. There is likely additional logging output above.
14513 verbose exit [ 1, true ]
yunfan commented 5 years ago

@mcollina after installed the 12.0 using nvm , i still got problem when using npm i --save i guess there might be my kernel's too new to the target leveldb?

/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2528:44: note:   candidate expects 1 argument, 0 provided
In file included from /home/jyf/.node-gyp/12.0.0/include/node/v8-internal.h:14,
                 from /home/jyf/.node-gyp/12.0.0/include/node/v8.h:25,
                 from /home/jyf/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../src/batch.cc:1:
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2544:35: note: candidate: ‘v8::Local<v8::String> v8::Value::ToString(v8::Isolate*) const’
                     Local<String> ToString(Isolate* isolate) const);
                                   ^~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8config.h:322:3: note: in definition of macro ‘V8_DEPRECATE_SOON’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2544:35: note:   candidate expects 1 argument, 0 provided
                     Local<String> ToString(Isolate* isolate) const);
                                   ^~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8config.h:322:3: note: in definition of macro ‘V8_DEPRECATE_SOON’
   declarator __attribute__((deprecated(message)))
   ^~~~~~~~~~
In file included from ../src/database.h:18,
                 from ../src/batch.cc:5:
../src/leveldown.h:59:39: error: no matching function for call to ‘v8::String::Utf8Length()’
     to ## Sz_ = to ## Str->Utf8Length();                                       \
                                       ^
../src/batch.cc:110:3: note: in expansion of macro ‘LD_STRING_OR_BUFFER_TO_SLICE’
   LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jyf/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../src/batch.cc:1:
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2678:7: note: candidate: ‘int v8::String::Utf8Length(v8::Isolate*) const’
   int Utf8Length(Isolate* isolate) const;
       ^~~~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2678:7: note:   candidate expects 1 argument, 0 provided
In file included from ../src/database.h:18,
                 from ../src/batch.cc:5:
../src/leveldown.h:65:5: error: no matching function for call to ‘v8::String::WriteUtf8(char*&, int, NULL, v8::String::WriteOptions)’
     );                                                                         \
     ^
../src/batch.cc:110:3: note: in expansion of macro ‘LD_STRING_OR_BUFFER_TO_SLICE’
   LD_STRING_OR_BUFFER_TO_SLICE(key, keyBuffer, key)
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /home/jyf/.node-gyp/12.0.0/include/node/node.h:63,
                 from ../src/batch.cc:1:
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2738:7: note: candidate: ‘int v8::String::WriteUtf8(v8::Isolate*, char*, int, int*, int) const’
   int WriteUtf8(Isolate* isolate, char* buffer, int length = -1,
       ^~~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:2738:7: note:   no known conversion for argument 1 from ‘char*’ to ‘v8::Isolate*’
/home/jyf/.node-gyp/12.0.0/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = node::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)]’:
/home/jyf/.node-gyp/12.0.0/include/node/node_object_wrap.h:84:78:   required from here
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:9817:16: warning: cast between incompatible function types from ‘v8::WeakCallbackInfo<node::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<node::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
                reinterpret_cast<Callback>(callback), type);
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/jyf/.node-gyp/12.0.0/include/node/v8.h: In instantiation of ‘void v8::PersistentBase<T>::SetWeak(P*, typename v8::WeakCallbackInfo<P>::Callback, v8::WeakCallbackType) [with P = Nan::ObjectWrap; T = v8::Object; typename v8::WeakCallbackInfo<P>::Callback = void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)]’:
../../nan/nan_object_wrap.h:66:61:   required from here
/home/jyf/.node-gyp/12.0.0/include/node/v8.h:9817:16: warning: cast between incompatible function types from ‘v8::WeakCallbackInfo<Nan::ObjectWrap>::Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<Nan::ObjectWrap>&)’} to ‘Callback’ {aka ‘void (*)(const v8::WeakCallbackInfo<void>&)’} [-Wcast-function-type]
make: *** [leveldown.target.mk:125:Release/obj.target/leveldown/src/batch.o] 错误 1
make: 离开目录“/home/jyf/devel/repo/fastify-auth/node_modules/leveldown/build”
gyp ERR! build error
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/home/jyf/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:196:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:256:12)
gyp ERR! System Linux 5.0.0-15-generic
gyp ERR! command "/home/jyf/.nvm/versions/node/v12.0.0/bin/node" "/home/jyf/.nvm/versions/node/v12.0.0/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /home/jyf/devel/repo/fastify-auth/node_modules/leveldown
gyp ERR! node -v v12.0.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! leveldown@2.1.1 install: `prebuild-install || node-gyp rebuild`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the leveldown@2.1.1 install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/jyf/.npm/_logs/2019-05-29T02_40_50_058Z-debug.log
Eomm commented 5 years ago

Maybe you could just try to run to find which package gives you these troubles and ask them accordingly:

mkdir try
cd try
nvm use node
npm init --yes
npm i leveldown@2.1.1
yunfan commented 5 years ago

@Eomm sorry for boring you guys, i had sent issue to leveldown. still waiting. meanwhile, is it possible to ask which enviroment were you use when developing this. i was considering to use a docker based development enviroment

yunfan commented 5 years ago

according to https://github.com/Level/leveldown/issues/639 the problem could be solved by upgrade leveldown version to 5.0.0+ , but i dont know if it was allowed @Eomm @mcollina

Eomm commented 5 years ago

This is info is good to know (for fastify-leveldb plugin mainly) 👍

Regarding this problem instead, you could just use node 10 (using nvm install and nvm use) to develop this feature since leveldb it is only a devdep

yunfan commented 5 years ago

merged pr solved this