oauth2.0 在Chrome扩展程序中使用Google帐户进行服务器端身份验证

wko9yo5t  于 2023-10-15  发布在  Go
关注(0)|答案(2)|浏览(140)

我有一个Web应用程序,目前使用OAuth2来验证使用Google帐户的用户。流程非常标准:用户登录到Google,Web应用程序会收到一个回调,检索用户身份并将其存储在会话中。
现在我需要创建一个附带的Chrome扩展。此扩展需要访问下面的Web应用程序,因此它需要对此应用程序进行身份验证。我使用the official documentation配置了我的扩展,但在实验过程中,我意识到这不是我需要的。因为它使用OAuth2 * 隐式流 *,所以它不返回可以在服务器端验证的令牌。这个流程只适合在客户端使用Google API,这不是我的用例。这个文档(以及我在网上找到的几乎所有其他东西)集中在两种可能的情况下:
1.我们希望在扩展端访问Google API(chrome.identity.getAuthToken())。
1.我们希望使用替代OAuth2服务(chrome.identity.launchWebAuthFlow())进行身份验证。
然而,在我的情况下,我想使用Google帐户对用户进行身份验证,但在我的Web应用程序的服务器端处理令牌。我可以在这里使用选项2,但创建自己的“非Google身份验证服务”(它只是Google身份验证服务的 Package 器)对我来说并不“正确”,只能在服务器端进行身份验证。
选择2真的是唯一的方法吗?或者还有更简单的方法吗?
我还看到有人建议使用tokeninfo端点来验证令牌,但我发现很难确保这确实是一种“官方”和安全的方法。

b4lqfgs4

b4lqfgs41#

要检索可在应用的两个部分(扩展和服务器)上使用的访问令牌,您应该请求Google跨客户端访问令牌。这允许您在单个项目中注册两个应用程序(两个客户端ID)并共享访问令牌。
Google在这里描述和讨论了这一点:

粗略的步骤是:
1.您将需要两个clientId,一个用于扩展,另一个用于服务器应用
1.将两个clientId添加到单个项目
1.从扩展中删除跨客户端访问令牌
1.通过HTTPS发送到您的服务器
要在Chrome中执行此操作,看起来您需要使用回调函数调用chrome.identity.getAuthToken(),将令牌发送到您的Web应用。
参考文件在chrome.identity.getAuthToken()上说:

chrome.identity.getAuthToken(object details, function callback)

使用manifest.json的oauth2部分中指定的客户端ID和范围获取OAuth2访问令牌。
并且它可以接受指定的回调函数:
使用清单指定的OAuth2访问令牌调用,如果有错误则使用undefined。
如果你指定了回调参数,它应该是一个看起来像这样的函数:
function(string token) {...};

  • 参考:method-getAuthToken
ddrv8njm

ddrv8njm2#

我在我的项目中解决了这个问题,以下是步骤
步骤1创建2个OAuth 2.0客户端ID,一个用于Chrome扩展,一个用于Web应用image1
步骤2将它们添加到代码中

  • 分机号manifest.jsonimage2
  • (我使用Golang创建了一个Web应用程序)image3

步骤3在Chrome扩展中使用var token = await chrome.identity.getAuthToken({ interactive: true });获取身份验证令牌,并使用API将其发送到Web应用程序
下面是Golang代码,用于使用我们从扩展发送令牌创建客户端

func Login(c *gin.Context) {
form := LoginDto{}
    if err := c.ShouldBindJSON(&form); err != nil {
        c.String(http.StatusBadRequest, "Missing code google token")
        return
    }
    fmt.Println(form)
    //make client
    token, err := common.GetOauthConfig().TokenSource(c, &oauth2.Token{AccessToken: form.GoogleToken}).Token()
    if err != nil {
        c.String(http.StatusInternalServerError, fmt.Sprintf("Error token: %s", err))
        return
    }
    client := common.GetOauthConfig().Client(c, token)

//other logics
}

注意:两个客户端使用相同的作用域

相关问题