You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Mojolicious::Plugin::OAuth2获取Refresh Token

解决Mojolicious::Plugin::OAuth2获取Google Refresh Token的问题

我来帮你搞定这个获取Google Refresh Token的事儿,之前用这个插件对接Google OAuth2的时候,也踩过类似的坑,咱们一步步来梳理:

1. 补全Google Provider的关键配置

你已经加了access_type => 'offline'(这是获取refresh_token的核心前提),但还缺一个关键参数prompt => 'consent'。因为Google现在默认规则是:用户首次授权后,后续重复请求不会再返回refresh_token,只有强制让用户重新确认授权时才会触发返回。修改你的插件配置:

plugin OAuth2 => { 
  providers => { 
    google => { 
      key => 'somekey', 
      secret => 'somesecret', 
      redirect => 'http://localhost:3000/login/google', 
      access_type => 'offline', 
      prompt => 'consent',  # 强制触发refresh_token返回
      scope => join ' ', qw|some scopes|, 
    } 
  } 
};

2. 正确提取并存储Refresh Token

在你调用get_token_p的回调里,返回的$res对象其实已经包含了refresh_token字段,只是你之前只存了access_token。现在把它也妥善存储起来:

->then(sub { 
  my $res = shift; 
  return unless $res;
  
  # 同时保存access_token和refresh_token,建议存数据库而非仅session
  $c->session(
    token => $res->{access_token},
    refresh_token => $res->{refresh_token}
  ); 
  1; 
})

⚠️ 注意:只有用户首次授权,或者你加了prompt => 'consent'让用户重新授权时,$res里才会有refresh_token。所以第一次拿到后一定要存到持久化存储(比如数据库),避免session过期丢失。

3. 正确调用get_refresh_token_p刷新Token

你之前调用这个方法报错,大概率是参数传递不对。这个方法需要传入已保存的refresh_token,以及provider标识。正确的使用姿势如下:

# 从存储中取出之前保存的refresh_token
my $refresh_token = $c->session('refresh_token');

$c->oauth2->get_refresh_token_p(google => { refresh_token => $refresh_token })
  ->then(sub {
    my $new_token_data = shift;
    
    # 更新session里的access_token,若返回新的refresh_token也一并更新
    $c->session(
      token => $new_token_data->{access_token},
      refresh_token => $new_token_data->{refresh_token} || $refresh_token
    );
    
    # 后续逻辑:比如重新获取用户信息等
  })
  ->catch(sub {
    my $err = shift;
    $c->log->error("刷新Token失败: $err");
    $c->render(text => "Token刷新出错: $err");
  });

这个方法会自动用你配置的provider key和secret,向Google的Token端点请求新的access_token,部分情况下还会返回新的refresh_token,记得一并更新存储。

4. 额外排查要点

  • 检查Google Cloud Console配置:确保你的OAuth同意屏幕已发布(测试阶段可用内部测试),且重定向URI和代码里的redirect参数完全一致,包括协议(http/https)、端口和路径。
  • 测试前清除旧授权:在Google账户的「安全」→「第三方应用访问权限」里找到你的应用并移除授权,这样第一次请求一定会返回refresh_token,方便验证逻辑。

内容的提问来源于stack exchange,提问作者simone

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:32:48