manjeshpv / node-oauth2-server-implementation

Using oauth2-server: 3.0.0-b2 & Supports MongoDB, MySQL, PostgreSQL, MSSQL & SQLite
216 stars 103 forks source link

Invalid scope: Requested scope is invalid #8

Closed sebsn86 closed 7 years ago

sebsn86 commented 7 years ago

Hi,

I have just imported your project, added tables in database, configured the MariaDB connection and imported your Postman collection, but when i try your "Password Grant" call in Postman, i have this error :

{
  "message": "Invalid scope: Requested scope is invalid",
  "code": 400,
  "name": "invalid_scope"
}

An idea ?

best regards

sebsn86 commented 7 years ago

It seems like the validateScope function in models.js has the undefined token parameter. Where this function is invoke ?

zakariaDM commented 7 years ago

Same problèm here, it works when i'am in local machine, but i get the problème when i use my linux server

mihailj commented 7 years ago

Hello guys,

The validateScope function has the parameters 'user' and 'client'.

You can see here:

https://github.com/oauthjs/node-oauth2-server/blob/master/lib/grant-types/password-grant-type.js#L105

So it should look like:

function validateScope(user, client) {
  return user.scope === client.scope
}

I also had a custom user table and forgot to add the 'scope' field before getting to this error, so you might want to also check this if it still doesn't work.

pangpond commented 7 years ago

yes, It's work after change models.js from

function validateScope(token, scope) {
   return token.scope === scope
}

to

function validateScope(user, client) {
  return user.scope === client.scope
}

thank @mihailj

mihailj commented 7 years ago

Actually there is an error in my code, it should return the actual scope (not boolean true) or false, as I've found from here: https://github.com/oauthjs/node-oauth2-server/issues/335

The function also has a 3rd parameter scope.

So a better implementation would be:

function validateScope(user, client, scope) {
  return (user.scope === scope && client.scope === scope && scope !== null)?scope:false
}
kosicki123 commented 7 years ago

Hi, I've cloned the repository and tried both MySQL and mongo examples. In MySQL, I can't access the /profile route, everything else works perfectly. The error is: { "message": "Invalid scope: Requested scope is invalid", "code": 400, "name": "invalid_scope" }

In mongo, everything just works, not sure why. I had to change the validateScope method to: function validateScope(user, client) { return user.scope === client.scope }

and make use of the open pull request in both models to: verifyScope: validateScope

The problem is, in both database examples, scope is null, why is that? I've imported the seeds correctly and my databases are well populated. Also, I don't understand why it works on mongo.

Hope you guys can help me with this.

Thanks!

mihailj commented 7 years ago

Hello @kosicki123 ,

The verifyScope function should be different from validateScope:

function verifyScope(token, scope) {
  return token.scope === scope
}

Also check out my implementation above for the validateScope function that returns the actual scope.

For MySQL you also have to set scope for the client in oauth_clients table.

Hope this helps, Mihail

kosicki123 commented 7 years ago

Thanks for the reply @mihailj !

Now I've implemented both exactly as your code and inserted the profile scope in my client. My module.exports is looking like this: verifyScope: verifyScope, validateScope: validateScope

Is it correct to put both ? With both, I get the same error invalid scope. If I use your verifyScope, I got token.scope = null which leads to invalid scope as well. I tried to insert my scope directly in my access token in my database, but the result is the same.

Any clue?

Thanks for your help!

mihailj commented 7 years ago

Looks like the scope field is missing in 2 functions from components/oauth/models.js.

function getClient - line 41 should be:

attributes: ['id', 'client_id', 'redirect_uri', 'scope'],

function getUser - line 67 should be:

attributes: ['id', 'username', 'password', 'scope'],

You also add scope: profile in your POST request and it will return the token.

You can also check the source code of my project https://github.com/mihailj/MapTrialsServer where is a slightly modified version of this that works with scopes.

kosicki123 commented 7 years ago

@mihailj Thanks a lot for your help! That seems to resolve all my problems! I'll check your implementation!

sebsn86 commented 7 years ago

Hi guys,

Sorry for the late but I tried this configuration :

function verifyScope(token, scope) { return token.scope === scope; }

I have added the scope property in getUser and getClient functions too, but the token.scope value is 1 and scope "profile". What I missed ?

Best regards

mihailj commented 7 years ago

@sebsn86 the validateScope function should return the actual scope and save it in the database, not the boolean result:

function validateScope(user, client, scope) {
  return (user.scope === scope && client.scope === scope && scope !== null)?scope:false
}

See above my correction.

If you have saved the boolean true (1) the verifyScope function which is correct will not work.

kosicki123 commented 7 years ago

The parameters os validateScope are wrong in the latest commit: function validateScope(token, client, scope) { console.log("validateScope", token, client, scope) return (user.scope === client.scope) ? scope : false }

It's using undefined user parameter. Scope is always undefined for some reason. Also, I have a doubt. Why and how should I use client roles? Users already got roles, why it's needed to compare with the client role?

Should I have 1 client per user?