跳转到主要内容

概览

Laravel Bluesky 支持两种认证方式。完成认证后,两种方式调用 API 的方法是通用的。
项目App PasswordOAuth
内部类LegacyAgent / LegacySessionOAuthAgent / OAuthSession
入口Bluesky::login()Bluesky::withToken(OAuthSession)
私钥不需要需要 BLUESKY_OAUTH_PRIVATE_KEY
用户授权操作不需要需要(在浏览器中批准)
后台执行✅ 擅长✅ 可以(保存 refresh_token)
会话 keyaccessJwt / refreshJwtaccess_token / refresh_token
是否即将废弃不会
主要用途自动发帖、通知、批处理代表用户操作、Socialite 集成
LegacyAgent 这个命名表示的是“OAuth 之前的认证方式”,但 App Password 本身并没有废弃计划。在通知、自动发帖等无需用户操作的场景中,App Password 更简单,也更合适。

架构

BlueskyManager 是 Facade Bluesky 的具体实现。使用 login()withToken() 设置 agent 后,之后的 API 调用在两种认证方式下使用相同的方法。

App Password (LegacyAgent)

认证流程

Bluesky::login()

只需在 .env 中配置 App Password 并调用 login()
BLUESKY_IDENTIFIER=your-handle.bsky.social
BLUESKY_APP_PASSWORD=xxxx-xxxx-xxxx-xxxx
use Revolution\Bluesky\Facades\Bluesky;

$response = Bluesky::login(
    identifier: config('bluesky.identifier'),
    password: config('bluesky.password'),
)->post('Hello Bluesky');

复用 LegacySession

如果每次都调用 login(),每次都会产生 API 请求。缓存并复用 session 会更加高效。
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;

// 首次登录并保存 session
Bluesky::login(
    identifier: config('bluesky.identifier'),
    password: config('bluesky.password'),
);
cache()->put('bluesky_session', Bluesky::agent()->session()->toArray(), now()->addDay());

// 之后从缓存中恢复
$session = LegacySession::create(cache('bluesky_session', []));
Bluesky::withToken($session);

// 如果 access token 过期,则刷新
if (! Bluesky::check()) {
    Bluesky::refreshSession();
}

$response = Bluesky::post('Hello from cached session');

LegacySession 的主要键

内容方法
accessJwtaccess tokentoken()
refreshJwtrefresh tokenrefresh()
didBluesky DIDdid()
handlehandlehandle()
email邮箱地址email()
active账号是否处于活跃状态active()

适用场景

  • 后台任务、队列处理中的自动发帖
  • 使用 Laravel Notification 通道进行的通知
  • 批处理、定时任务
  • 使用应用自身的账号发帖

OAuth (OAuthAgent)

认证流程

Bluesky::withToken()

将通过 Socialite 获取的 OAuthSession 传给 withToken()
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;

// 从 Laravel session 中恢复(Web 请求)
$session = OAuthSession::create(session('bluesky_session'));
$timeline = Bluesky::withToken($session)->getTimeline();
在后台任务或 Console 中,也可以用保存在数据库里的值组装 OAuthSession
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\OAuthSession;

$session = OAuthSession::create([
    'did'           => $user->did,
    'refresh_token' => $user->refresh_token,
    // 对于非 bsky.social 的账号,还需要指定 iss
    // 'iss'        => $user->iss,
]);

$response = Bluesky::withToken($session)
                   ->refreshSession()
                   ->post('Hello from OAuth');

OAuthSession 的主要键

内容方法
access_tokenaccess tokentoken()
refresh_tokenrefresh token(只能使用一次)refresh()
did / subBluesky DIDdid()
iss授权服务器 URLissuer()
profile.handlehandlehandle()
profile.displayName显示名displayName()
OAuth 的 refresh_token 只能使用一次。请通过 OAuthSessionUpdated 事件,在 token 更新后一定更新数据库。详情请参考 Socialite

适用场景

  • 通过 Socialite 实现用户登录
  • 代表用户调用 API
  • 需要针对每个用户使用不同账号进行操作的场景

认证之后的 API 调用是通用的

无论使用哪种认证方式,withToken() 之后使用的都是相同的 API 方法。
use Revolution\Bluesky\Facades\Bluesky;
use Revolution\Bluesky\Session\LegacySession;
use Revolution\Bluesky\Session\OAuthSession;

// App Password
Bluesky::login(config('bluesky.identifier'), config('bluesky.password'));

// 或者 OAuth
$session = OAuthSession::create(session('bluesky_session'));
Bluesky::withToken($session);

// ↓ 之后的 API 调用完全相同 ↓

Bluesky::post('Hello Bluesky');
Bluesky::getTimeline();
Bluesky::getProfile();
Bluesky::searchPosts(q: '#laravel');
BlueskyManager 在内部会根据情况使用 LegacyAgentOAuthAgent,但对调用方代码没有影响。

应该选哪种?

场景推荐
自动发帖、通知、批处理App Password
用户登录功能OAuth
只做后台任务App Password
需要代表用户操作OAuth
优先考虑运营简单App Password
重视安全性与权限控制OAuth
纠结时,按目的划分最直观。“应用自己动作”就用 App Password,“用户来操作”就用 OAuth。两者也可以组合使用,比如通知用 App Password、用户登录用 OAuth 是常见的组合。

参考链接

最后修改于 2026年7月13日