如何使用 Laravel 管理 OAuth 刷新令牌?
Posted
技术标签:
【中文标题】如何使用 Laravel 管理 OAuth 刷新令牌?【英文标题】:How can I manage OAuth refresh tokens with Laravel? 【发布时间】:2016-03-03 11:12:14 【问题描述】:Socialiate 插件在 Laravel 中提供了 OAuth 的实现,但它似乎主要是为了让他们不必在您自己的网站上创建用户帐户。
我正在制作一个帮助管理他们的 Youtube 帐户的应用程序,这意味着身份验证请求的范围更广(这很容易更改),但我还需要一个刷新令牌(而不是一个访问令牌)以进行长期访问到他们的帐户。
Laravel 是否有一个包已经可以处理这个问题?我一直找不到,但也许我在寻找错误的东西。
如果不是,我应该如何处理?当我编写与 Youtube 的 API 交互的代码时,我是否只需要检查访问令牌是否已过期,如果是,则编写一个执行 HTTP 请求的函数,以使用我存储在数据库?而且我想还扩展社交名流来检索刷新令牌?
我觉得一定有更好的方法,不需要我重新发明***。
【问题讨论】:
【参考方案1】:这很难找到信息,部分原因是 Laravel 的 OAuth2-server 包提供了自己的 OAuth 解决方案,这是大部分搜索结果。
我认为最好的答案是为社交名流编写自己的 YoutubeProvider。这是一个教程:https://medium.com/laravel-news/adding-auth-providers-to-laravel-socialite-ca0335929e42#.6bn8i2wz4
更改社交名流以开始使用刷新令牌会很痛苦,所以我认为最好的方法是让 YoutubeProvider 在现有 getAccessToken 函数的末尾额外调用一个新的 getRefreshToken 函数。更改访问令牌和刷新令牌以将检索到的令牌保存到数据库中,因为社交名流不会让您选择访问刷新令牌以将其保存在帮助程序/控制器类中。
创建一个 Tokens 模型和数据库表,并在其中存储与 User 模型相关的访问和刷新令牌。
当您编写 YoutubeService 帮助程序时,它需要能够尝试使用访问令牌进行 API 调用,并知道在收到过期/无效的错误消息时使用刷新令牌刷新它。
Google 的 php API 库似乎可以通过 $client->setAccessType("offline")
自动处理这个问题:https://developers.google.com/api-client-library/php/auth/web-app
但是一旦您开始需要 Google 以外的其他东西的刷新令牌,如果新的提供者也没有库,那么无论如何您都将编写该代码。从好的方面来说,这个库有一个专门用于 Youtube 的服务,所以它应该处理你可能需要的所有对 Youtube 的 API 调用。我不完全确定使用这个库将如何与 Socialite 相结合,因为 Socialite 似乎已经做了很多这个库所做的事情。除非您真的想开始自定义内容,否则您可能会在 YoutubeService 类中进行某种冗余授权。
可能值得考虑将社交名流从等式中完全移除,并在涉及到他们的服务时使用 Google 的库。
【讨论】:
【参考方案2】:自从上次访问此问题以来已经有一段时间了,看到这是第一个 Google 搜索结果,我想说:社交名流现在可以做到这一点。
当您将用户重定向到 Google 时,在重定向时使用 with()
方法将 access_type
设置为 offline
,如下所示:
return Socialite::driver('google')
->scopes() // For any extra scopes you need, see https://developers.google.com/identity/protocols/googlescopes for a full list; alternatively use constants shipped with Google's PHP Client Library
->with(["access_type" => "offline", "prompt" => "consent select_account"])
->redirect();
这将使 Google 返回一个刷新令牌。
【讨论】:
这应该是最佳答案 tbh以上是关于如何使用 Laravel 管理 OAuth 刷新令牌?的主要内容,如果未能解决你的问题,请参考以下文章
使用 Google Drive Oauth 2.0 管理访问令牌
如何刷新OAuth2令牌?我是否需要等待令牌过期? (Patreon API)