node-oauth2-server icon indicating copy to clipboard operation
node-oauth2-server copied to clipboard

parameter `client_id` and `client_secret` should be deleted, when grant_type is `password`

Open Lensual opened this issue 8 years ago • 10 comments

parameter client_id and client_secret should be deleted, when grant_type is password

https://tools.ietf.org/html/rfc6749#section-4.3

I got a error when i was calling oauth.token().

Invalid client: cannot retrieve client credentials

I'm using express-oauth-server 2.0.0. But I think, it's aboutoauth2-server 3.0.0.

options

router.oauth = new OAuthServer({
    model: memorystore,
    grants: ['password'],
    debug: true,
    useErrorHandler: true,
    continueMiddleware: true,
    requireClientAuthentication: { password: false }
});

request body

grant_type=password&username=admin&password=admin

Lensual avatar Aug 26 '17 19:08 Lensual

I'm using express-oauth-server 2.0.0. But I think, it's about oauth2-server 3.0.0.

Could you clarify what you mean by that?

The server option requireClientAuthentication is available starting with 3.0. If you're using 2.0 as you say that's probably why it's not working ;)

maxtruxa avatar Aug 28 '17 08:08 maxtruxa

Now, I'm sure the bugs is at oauth2-server 3.0.0, not at express-oauth-server 2.0.0.

rfc6749#section-4.3.2 This document defined the format of request. And for example here:

 POST /token HTTP/1.1
 Host: server.example.com
 Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
 Content-Type: application/x-www-form-urlencoded

 grant_type=password&username=johndoe&password=A3ddj3w

I call the function oauth.token().

When it creating a new object of TokenHandler, it always call the function getClient(). (line 90 at token-handler.js, caller by line 75 at server.js)

getClient() calling getClientCredentials() (line 116 at token-handler.js)

request.body.client_id and request.body.client_secret is undefined. That can make an exception.

Because there is not have client_id and client_secret by password.

Lensual avatar Aug 28 '17 20:08 Lensual

Look at the Authorization header. In your example from rfc, it's

Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW

After base64 decode it's

s6BhdRkqt3:gX1fBat3bV

So in this example, client_id is s6BhdRkqt3 and client_secret is gX1fBat3bV

visvk avatar Sep 04 '17 17:09 visvk

+1, same here. Can I do request to get token just with username and password without Authorization header?

wizardnet972 avatar Sep 25 '17 11:09 wizardnet972

This Auth header is optional in case:

If the client type is confidential or the client was issued client credentials (or assigned other authentication requirements), the client MUST authenticate with the authorization server as described in Section 3.2.1.

wizardnet972 avatar Sep 25 '17 12:09 wizardnet972

There is no much a different here.. if I use requireClientAuthentication, the oauth2 will get the Authorization from the body instead of header. like so:

  if (!this.isClientAuthenticationRequired(grantType)) {
    if(request.body.client_id) {
      return { clientId: request.body.client_id };
    }
  }

wizardnet972 avatar Sep 25 '17 12:09 wizardnet972

So are people abandoning this project? Grant password doesn't seem to work. Anyone care to fork it?

JonNeat avatar Jul 11 '18 19:07 JonNeat

This helps me:

// Model
module.exports.getClient = function *(clientId, clientSecret) {
  return { clientId, clientSecret, grants: ['password', 'refresh_token'] };
};

nmorozov avatar Sep 16 '18 10:09 nmorozov

Try adding requireClientAuthentication and set it to false and then pass a generic name (my-app) for your clientId when using the password grant

   this.oauthServer = new OAuth2Server({
            model: require('./shared/oauth.model-ts'),
            requireClientAuthentication: {password: false}
        });

brickolicious avatar Nov 09 '18 13:11 brickolicious

Try adding requireClientAuthentication and set it to false and then pass a generic name (my-app) for your clientId when using the password grant

   this.oauthServer = new OAuth2Server({
            model: require('./shared/oauth.model-ts'),
            requireClientAuthentication: {password: false}
        });

This worked for me!

goodeath avatar Apr 17 '20 05:04 goodeath