Closed fadiquader closed 5 years ago
I was just able to test this successfully with the current feathers-chat. It looks like the scope
has to be set to [ "email", "profile", "openid" ]
. If that works it makes probably sense to add it to the generator.
Also, oAuth host and protocol don't need to be set since it will usually be inferred from the global host
configuration and NODE_ENV
.
@daffl I created new creds with feathers-chat example, and it worked! Thank you so much for your help.
@daffl Small note on host
In my experience the production oauth callback URL usually isn't inferred correctly, because feathers includes the port: ${app.get('host')}:${app.get('port')}
, but if you're hosting behind a proxy like nginx or in something like heroku, the port is internal only and should not be part of the public callback url.
@KidkArolis You mentioned a good point, that's why i manually set the "host", "protocol" in the environment variables.
Hm... good point actually. It might make sense to leave the port out in production
. You can always override it locally. I'm wondering what went wrong in your original setup. I also noticed that Grant doesn't give a lot of information here, it might be worth digging into.
I am getting the same error with both facebook and google.
Here's my config:
{
"host": "localhost",
"port": 3030,
"public": "../public/",
"paginate": {
"default": 10,
"max": 200
},
"authentication": {
"entity": "user",
"service": "users",
"secret": "secret",
"authStrategies": [
"jwt",
"local"
],
"jwtOptions": {
"header": {
"typ": "access"
},
"audience": "https://yourdomain.com",
"issuer": "feathers",
"algorithm": "HS256",
"expiresIn": "30d"
},
"local": {
"usernameField": "email",
"passwordField": "password"
},
"oauth": {
"redirect": "OAUTH_REDIRECT_URL",
"facebook": {
"key": "FACEBOOK_APP_ID",
"secret": "FACEBOOK_APP_SECRET",
"scope": ["email, public_profile"]
},
"google": {
"key": "GOOGLE_PROJECT_ID",
"secret": "GOOGLE_PROJECT_SECRET",
"scope": [ "email", "profile", "openid" ]
}
}
},
"mongodb": "MONGODB_URL"
}
And this is my authentication
service
const { AuthenticationService, JWTStrategy } = require('@feathersjs/authentication');
const { LocalStrategy } = require('@feathersjs/authentication-local');
const { expressOauth, OAuthStrategy } = require('@feathersjs/authentication-oauth');
const axios = require('axios');
class FacebookStrategy extends OAuthStrategy {
async getProfile (authResult) {
// This is the oAuth access token that can be used
// for Facebook API requests as the Bearer token
const accessToken = authResult.access_token;
const { data } = await axios.get('https://graph.facebook.com/me', {
headers: {
authorization: `Bearer ${accessToken}`
},
params: {
// There are
fields: 'id,name,email,picture'
}
});
return data;
}
async getEntityData(profile) {
// `profile` is the data returned by getProfile
const baseData = await super.getEntityData(profile);
return {
...baseData,
isVerified: true,
displayName: profile.name,
name: profile.name,
email: profile.email
};
}
}
class GoogleStrategy extends OAuthStrategy {
async getEntityData(profile) {
// this will set 'googleId'
const baseData = await super.getEntityData(profile);
// this will grab the picture and email address of the Google profile
return {
...baseData,
isVerified: true,
profilePicture: profile.picture,
email: profile.email
};
}
}
module.exports = app => {
const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy());
authentication.register('local', new LocalStrategy());
authentication.register('facebook', new FacebookStrategy());
authentication.register('google', new GoogleStrategy());
app.use('/authentication', authentication);
app.configure(expressOauth());
};
It doesn't matter whether I accept or cancel the login request, it sends me to this url: http://localhost:3030/oauth/connect/google/callback?code=4%2FtQF8-vzUPx56ArlBz1WJYz3o5v_eQG0xSDZ87Xk41lA6K7cZXkk3gnpyGo5rnAwNVILxzQo_l6BHltHizyE7scs&scope=email%20profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid&authuser=0&session_state=31a9e2ae84bacfd25937d816f078ac409e57682e..3240&prompt=consent#
and there's always the same error: error=Grant%3A%20missing%20session%20or%20misconfigured%20provider
I updated all the libraries to the latest versions and still it's not working.
However, everything seems to be working fine when I use the feathers-chat app.
I tracked down the grant callback endpoint and I just wanted to see what are the values of the session
and provider
.
In my app, both of them were empty objects {}
, and this is why grant throws that error.
In the feathers-chat app, this is how they look like:
session { provider: 'facebook',
response: { error: { error: [Object] } } }
provider { authorize_url: 'https://www.facebook.com/dialog/oauth',
access_url: 'https://graph.facebook.com/oauth/access_token',
oauth: 2,
path: '/oauth',
host: 'localhost:3030',
protocol: 'http',
transport: 'session',
key: 'my_fb_app_key',
secret: 'my_fb_app_secret',
callback: 'http://localhost:3030/oauth/facebook/authenticate',
redirect_uri: 'http://localhost:3030/oauth/facebook/callback',
name: 'facebook',
facebook:
The `session` is `req.session.grant`. In my app, `req.session.grant` is not defined, while in the feathers-chat app, `req.session.grant` is `{ provider: 'facebook' }`
I'd be very happy to track it further, but I'm not familiar with feathers or feathers authentication. Can someone help me, please?
this might possibly help you. i had a similar issue and dealt directly with the author of grant. here is a future recipe:
https://github.com/feathersjs/docs/pull/1379
note the extra lines in the config file. i needed to have much more control over my callbacks.
Thank you,
Mark Edwards
On Mon, Nov 18, 2019 at 3:16 PM Dan Lupascu notifications@github.com wrote:
I am getting the same error with both facebook and google.
Here's my config:
{ "host": "localhost", "port": 3030, "public": "../public/", "paginate": { "default": 10, "max": 200 }, "authentication": { "entity": "user", "service": "users", "secret": "secret", "authStrategies": [ "jwt", "local" ], "jwtOptions": { "header": { "typ": "access" }, "audience": "https://yourdomain.com", "issuer": "feathers", "algorithm": "HS256", "expiresIn": "30d" }, "local": { "usernameField": "email", "passwordField": "password" }, "oauth": { "redirect": "OAUTH_REDIRECT_URL", "facebook": { "key": "FACEBOOK_APP_ID", "secret": "FACEBOOK_APP_SECRET" }, "google": { "key": "GOOGLE_PROJECT_ID", "secret": "GOOGLE_PROJECT_SECRET", "scope": [ "email", "profile", "openid" ] } } }, "mongodb": "MONGODB_URL" }
And this is my authentication service
const { AuthenticationService, JWTStrategy } = require('@feathersjs/authentication'); const { LocalStrategy } = require('@feathersjs/authentication-local'); const { expressOauth, OAuthStrategy } = require('@feathersjs/authentication-oauth'); const axios = require('axios');
class FacebookStrategy extends OAuthStrategy { async getProfile (authResult) { // This is the oAuth access token that can be used // for Facebook API requests as the Bearer token const accessToken = authResult.access_token;
const { data } = await axios.get('https://graph.facebook.com/me', { headers: { authorization: `Bearer ${accessToken}` }, params: { // There are fields: 'id,name,email,picture' } }); return data;
}
async getEntityData(profile) { //
profile
is the data returned by getProfile const baseData = await super.getEntityData(profile);return { ...baseData, displayName: profile.name, name: profile.name, email: profile.email };
} }
module.exports = app => { const authentication = new AuthenticationService(app);
authentication.register('jwt', new JWTStrategy()); authentication.register('local', new LocalStrategy()); authentication.register('facebook', new FacebookStrategy()); authentication.register('google', new OAuthStrategy());
app.use('/authentication', authentication); app.configure(expressOauth()); };
It doesn't matter whether I accept or cancel the login request, it sends me to this url: http://localhost:3030/oauth/connect/google/callback?code=4%2FtQF8-vzUPx56ArlBz1WJYz3o5v_eQG0xSDZ87Xk41lA6K7cZXkk3gnpyGo5rnAwNVILxzQo_l6BHltHizyE7scs&scope=email%20profile%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid&authuser=0&session_state=31a9e2ae84bacfd25937d816f078ac409e57682e..3240&prompt=consent# and there's always the same error: error=Grant%3A%20missing%20session%20or%20misconfigured%20provider
I updated all the libraries to the latest versions and still it's not working.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/feathersjs/feathers/issues/1515?email_source=notifications&email_token=AAWJ3YS2LMYYHJOWRZEQBSLQUMH4PA5CNFSM4INR2PF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEMDLYY#issuecomment-555234787, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWJ3YXYLL5TVPBFREJ7ILLQUMH4PANCNFSM4INR2PFQ .
this might possibly help you. i had a similar issue and dealt directly with the author of grant. here is a future recipe: feathersjs/docs#1379 note the extra lines in the config file. i needed to have much more control over my callbacks. Thank you, Mark Edwards
Hey. Which extra lines have you added in the config file? I see that you have "redirect_uri" and "callback" properties for each provider but I already tried that and it's still not working.
If you have a look at the Google oAuth cookbook entry you can see that you have to set the nonce
option in the the configuration if you are requesting the email
scope.
I just tried with nonce
and it's still not working.
Here's the new config:
"oauth": {
"redirect": "/",
"facebook": {
"key": "FACEBOOK_APP_ID",
"secret": "FACEBOOK_APP_SECRET",
"scope": ["email, public_profile"]
},
"google": {
"key": "GOOGLE_PROJECT_ID",
"secret": "GOOGLE_PROJECT_SECRET",
"scope": [ "email", "profile", "openid" ],
"nonce": true
}
}
the author of Grant suggested to me i first get the Grant example working standalone, which solved my issue.
Thank you,
Mark Edwards
On Mon, Nov 18, 2019 at 6:47 PM Dan Lupascu notifications@github.com wrote:
I just tried with nonce and it's still not working.
Here's the new config:
"oauth": { "redirect": "/", "facebook": { "key": "FACEBOOK_APP_ID", "secret": "FACEBOOK_APP_SECRET", "scope": ["email, public_profile"] }, "google": { "key": "GOOGLE_PROJECT_ID", "secret": "GOOGLE_PROJECT_SECRET", "scope": [ "email", "profile", "openid" ], "nonce": true } }
— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/feathersjs/feathers/issues/1515?email_source=notifications&email_token=AAWJ3YRKP4WFPBTBKBBPI6DQUNATNA5CNFSM4INR2PF2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEEMRXXQ#issuecomment-555293662, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWJ3YUBVHWBYA7LDJTKJDTQUNATNANCNFSM4INR2PFQ .
That entry also says that:
The scope value must begin with the string
openid
and then include profile or email or both
So your configuration should be
"scope": [ "openid", "email", "profile" ],
That entry also says that:
The scope value must begin with the string
openid
and then include profile or email or bothSo your configuration should be
"scope": [ "openid", "email", "profile" ],
Still not working.
Note that I'm getting the same result, no matter the provider. So, both of the callbacks (facebook and google) return the same error.
By the way, the grant configuration looks fine, this is what I get when I display the grant configuration after the app is configured (console.info(app.get('grant'));
)
{ defaults:
{ path: '/oauth',
host: 'localhost:3030',
protocol: 'http',
transport: 'session' },
facebook:
{ authorize_url: 'https://www.facebook.com/dialog/oauth',
access_url: 'https://graph.facebook.com/oauth/access_token',
oauth: 2,
path: '/oauth',
host: 'localhost:3030',
protocol: 'http',
transport: 'session',
key: 'key',
secret: 'secret',
callback: 'http://localhost:3030/oauth/facebook/authenticate',
redirect_uri: 'http://localhost:3030/oauth/facebook/callback',
name: 'facebook',
facebook: true },
google:
{ authorize_url: 'https://accounts.google.com/o/oauth2/auth',
access_url: 'https://accounts.google.com/o/oauth2/token',
oauth: 2,
scope_delimiter: ' ',
custom_parameters:
[ 'access_type',
'approval_prompt',
'login_hint',
'include_granted_scopes',
'prompt',
'display',
'hd' ],
path: '/oauth',
host: 'localhost:3030',
protocol: 'http',
transport: 'session',
key: 'key',
scope: 'openid email profile',
nonce: true,
callback: 'http://localhost:3030/oauth/google/authenticate',
redirect_uri: 'http://localhost:3030/oauth/google/callback',
name: 'google',
google: true } }
It seems that I managed to make it work
I really don't know what was the problem though ... at first I thought that it was because of the redirect
property but if it still works even if I change it to how it was in the previous config.
Here's my current config:
"oauth": {
"redirect": "OAUTH_REDIRECT_URL",
"facebook": {
"key": "FACEBOOK_APP_ID",
"secret": "FACEBOOK_APP_SECRET",
"scope": ["email", "public_profile"],
"redirect_uri": "FACEBOOK_REDIRECT_URI",
"callback": "FACEBOOK_CALLBACK"
},
"google": {
"key": "GOOGLE_PROJECT_ID",
"secret": "GOOGLE_PROJECT_SECRET",
"scope": ["openid", "email", "profile"],
"redirect_uri": "GOOGLE_REDIRECT_URI",
"callback": "GOOGLE_CALLBACK",
"nonce": true
}
}
Note that I had to set the redirect_uri
and callback
for each provider (thank you @edwardsmarkf ) because in production it was still redirecting me to localhost:port.
Really, it's very strange and I'd investigate it further but I already spent one day on this and I'll just let it go.
Redirect URLs should be inferred from the top level host
setting in the configuration. That's what I've been meaning to look into. @edwardsmarkf, @danlupascu have either of you updated the host
setting in production.json
? It's set to <name>-app.feathersjs.com
by default.
My production host is localhost
. However, when the redirect_uri
or callback
are created, the port is also added to the url, but I don't have a port in production. What should I change it to? Now it's 3030
.
It seems that I managed to make it work
I really don't know what was the problem though ... at first I thought that it was because of the
redirect
property but if it still works even if I change it to how it was in the previous config.Here's my current config:
"oauth": { "redirect": "OAUTH_REDIRECT_URL", "facebook": { "key": "FACEBOOK_APP_ID", "secret": "FACEBOOK_APP_SECRET", "scope": ["email", "public_profile"], "redirect_uri": "FACEBOOK_REDIRECT_URI", "callback": "FACEBOOK_CALLBACK" }, "google": { "key": "GOOGLE_PROJECT_ID", "secret": "GOOGLE_PROJECT_SECRET", "scope": ["openid", "email", "profile"], "redirect_uri": "GOOGLE_REDIRECT_URI", "callback": "GOOGLE_CALLBACK", "nonce": true } }
Note that I had to set the
redirect_uri
andcallback
for each provider (thank you @edwardsmarkf ) because in production it was still redirecting me to localhost:port.Really, it's very strange and I'd investigate it further but I already spent one day on this and I'll just let it go.
Do you inject variables into .json ? I'm currently trying to find a solution to inject production
variables into config. We don't want to store production keys in .json files on our repository.
Curently, I'm using a script which reads ENV vars, updates json and overwrites the file.
Is there another solution ?
{
"google": {
"key": "**",
"secret": "**",
"scope": ["email", "profile", "openid"],
"nonce": true
},
"github": {
"key": "**",
"secret": "**"
}
}
My config works in localhost but not working in my domain account.seongland.com
{
"redirect_uri": "https://account.seongland.com/oauth/google/callback",
"callback": "/oauth/google/authenticate"
}
"subdomain": "account",
I tested to add this configs, but both did not worked (or added together)
/oauth/connect/github or google/callback?code=**
this page shows
error=Grant%3A%20missing%20session%20or%20misconfigured%20provider
Error
My localhost config is working but I can't configure why my production configuration is not working
The only difference is host, key, secret, port
Is there any information related to this issue?
I am having the same problem as @seonglae If anyone found a solution, please let me know
I am also having the same problem as @seonglae @yonatann If anyone found a solution, please let me know
Good lord why is this still a hastle after so many years lol, Im having the same issue after making the application live to production in the google console and after the consent screen I just get sent this.
this is the url it tried to redirect to. https://aquaprime-backend.up.railway.app/auth/google/oauth2callback?code=4%2F0AeaYSHAsyJAWUUEUm_90lORoDR4z8B7PKYf3YtEzpz4iFACjfbcCW7PUxnmbD_oEcsbNqw&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email&authuser=0&prompt=consent
Google oauth was working properly when I was using v3, but after I migrated to v4, I was unable to authenticate anymore. After I authenticate using Google it redirects to https://exampe.com/oauth/connect/google/callback?code=..... and displays the following error on the page:
default.json
authentication.js
app.js
Thanks in advance for any advice!