I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the document using the "Browser App" option. /docs/advanced-guides/oauth-client
I'm requesting the following scopes, which (from /blog/oauth-atproto) are all of the scopes supported by Bluesky
scope: 'atproto transition:generic transition:chat.bsky
atproto = required transition:generic = the same level of permissions as an App Password transition:chat.bsky = adds access to the chat.bsky.* which isn't related to this question
During OAuth, bsky.social shows the follow permissions being granted:
- Uniquely identify you
- Access your chat messages
- Access your account data (except chat messages)
Once I get the JWT access token I can make requests to get records no problem:
- /xrpc/com.atproto.repo.listRecords
But the moment I try and write to the API using the JWT I get the following response:
{
"error": "InvalidToken",
"message": "Bad token scope"
}
from endpoints com.atproto.repo.createRecord or com.atproto.repo.putRecord
I'm not sure why this occurs considering I've got permission to all scopes. Authenticating with com.atproto.server.createSession and using the JWT from that response works fine, but I can't use this endpoint for customers as it requires them passing the username and password.
I'm trying to build an app that integrates with bsky's OAuth and API. Using the below the document using the "Browser App" option. https://docs.bsky.app/docs/advanced-guides/oauth-client
I'm requesting the following scopes, which (from https://docs.bsky.app/blog/oauth-atproto) are all of the scopes supported by Bluesky
scope: 'atproto transition:generic transition:chat.bsky
atproto = required transition:generic = the same level of permissions as an App Password transition:chat.bsky = adds access to the chat.bsky.* which isn't related to this question
During OAuth, bsky.social shows the follow permissions being granted:
- Uniquely identify you
- Access your chat messages
- Access your account data (except chat messages)
Once I get the JWT access token I can make requests to get records no problem:
- https://bsky.social/xrpc/com.atproto.repo.listRecords
But the moment I try and write to the API using the JWT I get the following response:
{
"error": "InvalidToken",
"message": "Bad token scope"
}
from endpoints com.atproto.repo.createRecord or com.atproto.repo.putRecord
I'm not sure why this occurs considering I've got permission to all scopes. Authenticating with com.atproto.server.createSession and using the JWT from that response works fine, but I can't use this endpoint for customers as it requires them passing the username and password.
Share Improve this question edited 10 hours ago marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 24 at 0:51 BobbyZHolmesBobbyZHolmes 7357 silver badges12 bronze badges1 Answer
Reset to default 0I've been fighting my way through this same set of issues. I'm not all the way there yet, but here's a summary of what I've found so far. Depending on what language you use, there are some working examples out there. Two that helped me were: https://github/bluesky-social/cookbook/tree/main/python-oauth-web-app and https://pkg.go.dev/github/potproject/atproto-oauth2-go-example.
Implementing OAuth with Bluesky API: The Missing Manual
Overview
Authenticating with Bluesky using OAuth is significantly more complex than traditional OAuth implementations due to Bluesky's use of advanced security mechanisms like DPoP (Demonstrating Proof of Possession) and their multi-tiered API architecture. This guide outlines the key requirements and steps for successfully implementing OAuth authentication with Bluesky.
Authentication Architecture Understanding
Bluesky's API consists of two main components:
- Personal Data Server (PDS) - Stores user data and provides endpoints for interacting with a user's own content
- AppView API - Provides endpoints for viewing and interacting with other users' content
Important: OAuth tokens can only be used with PDS endpoints, not with AppView endpoints.
Key Requirements
1. OAuth Flow Requirements
- You must implement the Authorization Code flow
- PKCE (Proof Key for Code Exchange) is required
- Client metadata must be publicly available at a HTTPS URL
- PAR (Pushed Authorization Requests) is required
2. DPoP Authentication
- All requests must use DPoP for proof of possession
- The Authorization header format is
Authorization: DPoP <token>
(notBearer <token>
) - DPoP tokens must be generated with the ES256 algorithm (P-256 curve)
- Each DPoP token must include:
- A unique JTI (JWT ID)
- The HTTP method (htm) for the request
- The exact target URL (htu) for the request
- The current server-provided nonce after the first request
3. API Access Limitations
- OAuth tokens only work with PDS endpoints (
/xrpc/com.atproto.*
) - OAuth tokens do not work with AppView endpoints (
/xrpc/app.bsky.*
) - To access user profile info, use the PDS endpoint (
/xrpc/com.atproto.repo.getRecord
) with appropriate parameters
Implementation Steps
1. Client Registration
Create a client metadata JSON file available at a public HTTPS URL:
{
"client_id": "https://your-app/.well-known/bluesky-oauth.json",
"application_type": "web",
"client_name": "Your App Name",
"client_uri": "https://your-app",
"dpop_bound_access_tokens": true,
"require_pkce": true,
"grant_types": [
"authorization_code",
"refresh_token"
],
"redirect_uris": [
"https://your-app/auth/bluesky/callback"
],
"response_types": [
"code"
],
"scope": "atproto transition:generic transition:chat.bsky",
"token_endpoint_auth_method": "none"
}
2. Authorization Request
- Generate a PKCE code verifier and challenge
- Redirect user to Bluesky's authorization URL with:
client_id
(URL to your metadata JSON)redirect_uri
response_type
= "code"scope
= "atproto transition:generic transition:chat.bsky"code_challenge
andcode_challenge_method
= "S256"state
(security token)
3. Token Exchange with DPoP
- Generate a P-256 key pair for DPoP
- Create a DPoP token for the token exchange request with the token endpoint URL
- Exchange the authorization code for tokens:
grant_type
= "authorization_code"code
= received code from authorizationredirect_uri
= same as in authorization requestcode_verifier
= PKCE verifier from step 2client_id
= URL to your metadata JSON
- Include
DPoP
header with the DPoP token - Handle DPoP nonce from the server response for subsequent requests
4. Making API Requests
- Generate a new DPoP token for each request
- Use
Authorization: DPoP <access_token>
in the header - Include the DPoP token in the DPoP header
- Include the server-provided nonce in subsequent DPoP tokens
- Only use PDS endpoints (those starting with
/xrpc/com.atproto.*
) - Handle responses properly, including new nonces
5. Profile Information Access
To get user profile info:
GET /xrpc/com.atproto.repo.getRecord?repo=<user-did>&collection=app.bsky.actor.profile&rkey=self
The response structure is complex, with nested objects:
{
"uri": "at://did:plc:abc123/app.bsky.actor.profile/self",
"cid": "bafyreiabc123...",
"value": {
"$type": "app.bsky.actor.profile",
"displayName": "User Name",
"description": "Bio text",
"avatar": {
"$type": "blob",
"ref": {
"$link": "bafkreiabc123..."
},
"mimeType": "image/jpeg",
"size": 12345
}
}
}
Common Pitfalls and Solutions
"Bad token scope" error:
- Ensure you're using
DPoP
(notBearer
) in the Authorization header - Make sure your DPoP token is signed with ES256
- Verify you're accessing PDS endpoints, not AppView endpoints
- Ensure you're using
DPoP nonce issues:
- Always store and reuse the most recent nonce from the server
- Create a new DPoP token for each request
- Handle the nonce retry flow correctly
Avatar image access:
Avatar URLs must be constructed from the response:
<endpoint>/xrpc/com.atproto.sync.getBlob?did=<user-did>&cid=<avatar-cid>
Handle retrieval:
- The getSession endpoint doesn't work with OAuth
- Extract handle from other responses or store it when initially retrieved
Limitations
The OAuth implementation in Bluesky currently has these limitations:
- OAuth tokens can only access PDS endpoints (not AppView endpoints)
- Some operations will require using other authentication methods
- OAuth implementation differs from typical OAuth flows by requiring DPoP
For full API access, you may need to implement a hybrid approach using both OAuth for PDS endpoints and other authentication methods for AppView endpoints.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744264438a4565797.html
评论列表(0条)