oauthjs / node-oauth2-server

Complete, compliant and well tested module for implementing an OAuth2 Server/Provider with express in node.js
https://npmjs.org/package/oauth2-server
MIT License
4.02k stars 931 forks source link

ServerErrors & ConsoleSpam happening for typical events in v2.4.1 when used with express #411

Open subatomicglue opened 7 years ago

subatomicglue commented 7 years ago

I am seeing errors happening for typical events like bad password or invalid token in oauth2-server v2.4.1 when used with express.

How do I prevent these errors spewing from my express service?

OAuth2Error: The access token provided is invalid.
    at OAuth2Error (.../node_modules/oauth2-server/lib/error.js:30:12)
    at .../node_modules/oauth2-server/lib/authorise.js:114:19
    at Object.model.getAccessToken (.../src/oauth2-mysql-model.js:17:32)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

Configuration:

app.oauth = oauthserver({
    model: require('./oauth2-mysql-model'),
    //model: require('./oauth2-memory-model'), // do NOT use in PRODUCTION
    grants: ['password', 'refresh_token'],
    debug: true,
    accessTokenLifetime: null, // never expire
    refreshTokenLifetime: null, // never expire
    authCodeLifetime: 1200,
    clientIdRegex: /^[a-z0-9-_]{3,40}$/i,
    allowExtendedTokenAttributes: true, // return additional properties from model.saveToken() which will be included in the token response:
    passthroughErrors: false
  });

my model.getAccessToken is

model.getAccessToken = async function( bearerToken, callback ) {
  try {
    let result = await db.query( db.WRITE, 'SELECT access_token, client_id, expires, user_id FROM oauth_access_tokens WHERE access_token = ?', [bearerToken] );

    // this one just gives "server error"...  which is not informative
    //if (!result.length) return callback( "access token not found in the db (oauth_access_tokens)", null );

    // this is the line in the stacktrace above:
    //          at Object.model.getAccessToken ( .../src/oauth2-mysql-model.js:17:32)
    // this one at least gives the message "OAuth2Error: The access token provided is invalid", but outputs stacktrace spew onto the command line for a "normal event"  (someone giving a wrong token shouldn't be an exception, it happens!)...
    if (!result.length) return callback( undefined, null );

    var token = result[0];
    let user = await users.getUserFromID( token.user_id );
    let retval = {
      accessToken: token.access_token,
      clientId: token.client_id,
      // puts the user data into req.user
      user: {
        id: user.id,
        email: user.emails_obj[0].email
      },
      //userId: token.user_id, // puts the user data into req.user.id (undesirable for us)
      expires: token.expires
    };
    callback(null, retval);
  } catch (err) {
    return callback( err );
  }
};

Endpoints in express:

app.all('/oauth/token', app.oauth.grant());

app.get('/secretarea', app.oauth.authorise(), function (req, res) {
  let user = req.user;
  res.status(200).json({message:'Secret area', user: user});
});

app.use(app.oauth.errorHandler());

Is there a way to suppress?

subatomicglue commented 7 years ago

Summary of negative responses (from typical inputs). I'd rather not have console spam for these:

Get Oauth Token from /oauth/token, bad username or password in the request body:

{
  "code": 503,
  "error": "server_error",
  "error_description": "server_error"
}

console:

OAuth2Error: false
    at OAuth2Error (.../node_modules/oauth2-server/lib/error.js:30:12)
    at .../node_modules/oauth2-server/lib/grant.js:226:26
    at Object.model.getUser (.../src/oauth2-mysql-model.js:129:16)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

Get oauth token from /oauth/token, invalid Authorization: Basic string:

{
  "code": 400,
  "error": "invalid_client",
  "error_description": "Client credentials are invalid"
}

console:

OAuth2Error: Client credentials are invalid
    at OAuth2Error (.../node_modules/oauth2-server/lib/error.js:30:12)
    at .../node_modules/oauth2-server/lib/grant.js:141:19
    at Object.model.getClient (.../src/oauth2-mysql-model.js:47:32)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)

/secret endpoint call with 'authorise()' middleware, and invalid Bearer token:

{
  "code": 401,
  "error": "invalid_token",
  "error_description": "The access token provided is invalid."
}

console:

OAuth2Error: The access token provided is invalid.
    at OAuth2Error (.../node_modules/oauth2-server/lib/error.js:30:12)
    at .../node_modules/oauth2-server/lib/authorise.js:114:19
    at Object.model.getAccessToken (.../src/oauth2-mysql-model.js:18:32)
    at process._tickDomainCallback (internal/process/next_tick.js:129:7)
subatomicglue commented 7 years ago

How do I take control of this, and rid the console spam - customize the 503 and 400's to all be 401s, and give smarter reading responses than "server error".