带有Passportjs的Google登录未通过身份验证

问题描述 投票:1回答:3

我正在使用Sails with Passport进行身份验证。我正在使用passport-google-oauth(OAuth2Strategy)和passport-facebook来启用Google登录。

我不太熟悉Passport,如果这是一个菜鸟问题,请原谅。我已经通过Facebook设置了登录名,并且效果很好。使用Google,在允许访问该应用程序后,我确实会收到授权码,但最终我没有通过身份验证。我猜测相同的代码应同时适用于Facebook和Google,因为这些策略均基于oauth2。

我什至不知道共享什么代码,因为我使用的是Sails-generate-auth的自动生成的代码,但是请告诉我是否还有其他可以共享的代码。

关于为什么会发生这种情况的任何想法?该应用程序是本地托管的,但这不太可能成为问题,因为无论如何我都进入了授权阶段。

sails.js passport-google-oauth
3个回答
3
投票

我遇到了同样的问题,它位于here in in api/services/passport.js

// If the profile object contains a list of emails, grab the first one and
// add it to the user.
if (profile.hasOwnProperty('emails')) {
  user.email = profile.emails[0].value;
}
// If the profile object contains a username, add it to the user.
if (profile.hasOwnProperty('username')) {
  user.username = profile.username;
}

// If neither an email or a username was available in the profile, we don't
// have a way of identifying the user in the future. Throw an error and let
// whoever's next in the line take care of it.
if (!user.username && !user.email) {
  return next(new Error('Neither a username nor email was available'));
}

Google服务未返回profile.username属性

因此,该用户未保存在数据库中并且无法通过身份验证。然后是护照回调receives an empty user,因此是the function that handles errors is firedthe user is redirected to the login page

此更改允许将displayName属性用作username

// If the profile object contains a list of emails, grab the first one and
// add it to the user.
if (profile.hasOwnProperty('emails')) {
  user.email = profile.emails[0].value;
}
// If the profile object contains a username, add it to the user.
if (profile.hasOwnProperty('username')) {
  user.username = profile.username;
}


/** Content not generated BEGIN */
// If the username property was empty and the profile object
// contains a property "displayName", add it to the user.
if (!user.username && profile.hasOwnProperty('displayName')) {
  console.log(profile);  // <= Use it to check the content given by Google about the user
  user.username = profile.displayName;
}
/** Content not generated END */


// If neither an email or a username was available in the profile, we don't
// have a way of identifying the user in the future. Throw an error and let
// whoever's next in the line take care of it.
if (!user.username && !user.email) {
  return next(new Error('Neither a username nor email was available'));
}

您也可以使用profile.id属性,因为profile.displayName不一定是唯一的(即:两个Google帐户可以具有相同的displayName)。但是跨不同的服务也是如此:Twitter帐户也可以具有与Facebook帐户相同的用户名。如果两者都在您的应用程序上注册,您将遇到错误。这是sails-generate-auth生成的代码中的问题,您应该根据所需的行为对其进行调整。

如果此解决方案也对您有效,我会提出PR。


1
投票

好,因此最终证明这是API的已知问题。

TL; DR:如here所述,启用Google+ API和Contacts API。 (不必使用Contacts API,正如@ AlexisN-o在评论中指出的那样。我的设置在禁用Contacts API的情况下可以正常工作。这显然取决于您使用的范围。)

我相信这不是失败的好方法,因为这是一个API错误,可以防止它冒泡。无论如何,我挖了passport.authenticate以找出问题所在。最终,这将调用与策略相对应的包中定义的authenticate方法(在这种情况下为oauth2)。在这里(passport-google-oauth/lib/passport-google-oauth/oauth2.js)中,我发现accessToken确实是从Google处获取的,因此一切正常。这表明对令牌URL的请求存在问题。因此,我进一步冒险进入passport-oauth2/lib/strategy.js,最后设法记录了此错误:

{ [InternalOAuthError: failed to fetch user profile]
  name: 'InternalOAuthError',
  message: 'failed to fetch user profile',
  oauthError: 
   { statusCode: 403,
     data: '{
        "error": {
            "errors": [{
                  "domain": "usageLimits",
                  "reason": "accessNotConfigured",
                  "message": "Access Not Configured. The API (Google+ API) is not enabled for your project. Please use the Google Developers Console to update your configuration.",
                  "extendedHelp": "https://console.developers.google.com" 
            }],
            "code": 403,
            "message": "Access Not Configured. The API (Google+ API) is not enabled for your project. Please use the Google Developers Console to update your configuration." 
      }
    }'
} }

这对我来说是狩猎的结尾,错误搜索的第一个结果导致了正确的答案。不过很奇怪。


0
投票

我遇到了同样的问题,并通过执行此操作解决了问题:

在package.json中,将“ passport”值更改为“ ^ 0.4.0”,将“ passport-google-oauth”更改为“ ^ 2.0.0”。再次运行“ npm install”。

© www.soinside.com 2019 - 2024. All rights reserved.