Skip to content

Commit

Permalink
OAuth docs tweaks (#2679)
Browse files Browse the repository at this point in the history
* OAuth README copy edits

* OAuth: clarification about client_name being shown

* OAuth: re-write handle resolution privacy concern

* switch terminology from PWA to SPA

* Update packages/api/OAUTH.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/oauth/oauth-client-browser/README.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/oauth/oauth-client-browser/README.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/oauth/oauth-client-node/README.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/api/OAUTH.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/api/OAUTH.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/api/OAUTH.md

Co-authored-by: Hailey <me@haileyok.com>

* Update packages/api/OAUTH.md

Co-authored-by: Hailey <me@haileyok.com>

---------

Co-authored-by: Matthieu Sieben <matthieusieben@users.noreply.github.com>
Co-authored-by: Hailey <me@haileyok.com>
  • Loading branch information
3 people authored Aug 5, 2024
1 parent 3681c90 commit 7436874
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 44 deletions.
65 changes: 33 additions & 32 deletions packages/api/OAUTH.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Oauth based authentication in a PWA
# OAuth Client Quickstart

## Introduction

This document describes how to implement OAuth based authentication in a PWA, to
communicate with Bluesky's [[ATPROTO]] API.
This document describes how to implement OAuth based authentication in a
browser-based Single Page App (SPA), to communicate with
[atproto](https://atproto.com) API services.

## Prerequisites

- You need a web server, or at very least a static file server, to host your PWA.
- You need a web server - or at the very least a static file server - to host your SPA.

> [!TIP]
>
Expand All @@ -18,24 +17,24 @@ communicate with Bluesky's [[ATPROTO]] API.
> [!TIP]
>
> You can use a service like [GitHub Pages](https://pages.github.com/) to host
> your client metadata and PWA for free.
> your client metadata and SPA for free.
- You must be able to build and deploy a PWA to your server.
- You must be able to build and deploy a SPA to your server.

## Step 1: Create your client metadata

Based on your hosting server endpoint, you will first need to choose a
`client_id`. That `client_id` will be used to identify your client to Bluesky's
Authorization Servers. A `client_id` must be a URL that points to a JSON file
that contains your client metadata. The client metadata **must** contain a
`client_id`. That `client_id` will be used to identify your client to
Authorization Servers. A `client_id` must be a URL pointing to a JSON file
which contains your client metadata. The client metadata **must** contain a
`client_id` that is the URL used to access the metadata.

Here is an example client metadata.

```json
{
"client_id": "https://example.com/client-metadata.json",
"client_name": "Example PWA",
"client_name": "Example atproto Browser App",
"client_uri": "https://example.com",
"logo_uri": "https://example.com/logo.png",
"tos_uri": "https://example.com/tos",
Expand All @@ -52,7 +51,7 @@ Here is an example client metadata.

- `redirect_uris`: An array of URLs that will be used as the redirect URIs for
the OAuth flow. This should typically contain a single URL that points to a
page on your PWA that will handle the OAuth response. This URL must be HTTPS.
page on your SPA that will handle the OAuth response. This URL must be HTTPS.

- `client_id`: The URL where the client metadata is hosted. This field must be
the exact same as the URL used to access the metadata.
Expand Down Expand Up @@ -80,15 +79,16 @@ Here is an example client metadata.
> [!NOTE]
>
> To mitigate phishing attacks, the Authentication Server will typically _not_
> display the `client_uri`, `logo_uri` to the user. If you don't see your logo
> or client name during the authentication process, don't worry, this is normal.
> display the `client_uri` or `logo_uri` to the user. If you don't see your logo
> or client name during the authentication process, don't worry. This is normal.
> The `client_name` _is_ generally displayed for all clients.
Upload this JSON file so that it is accessible at the URL you chose for your
`client_id`.

## Step 2: Setup you PWA
## Step 2: Setup your SPA

Start by setting up your PWA. You can use any framework you like, or none at
Start by setting up your SPA. You can use any framework you like, or none at
all. In this example, we will use TypeScript and Parcel, with plain JavaScript.

```bash
Expand Down Expand Up @@ -130,7 +130,7 @@ Create an `src/index.html` file with the following content:
And an `src/app.ts` file, with the following content:

```typescript
console.log('Hello from PWA!')
console.log('Hello from atproto OAuth example app!')
```

Start the app in development mode:
Expand All @@ -152,7 +152,7 @@ ngrok as the `client_id`:
```json
{
"client_id": "https://<RANDOM_VALUE>.ngrok.app/client-metadata.json",
"client_name": "My First ATPROTO OAuth App",
"client_name": "My First atproto OAuth App",
"client_uri": "https://<RANDOM_VALUE>.ngrok.app",
"redirect_uris": ["https://<RANDOM_VALUE>.ngrok.app/"],
"grant_types": ["authorization_code"],
Expand Down Expand Up @@ -184,18 +184,19 @@ document.addEventListener('DOMContentLoaded', main)

> [!CAUTION]
>
> By using `https://bsky.app/` as the `handleResolver`, you are using Bluesky's
> servers as handle resolver. This has the advantage of not requiring you to
> host your own handle resolver, but it also means that Bluesky will be able to
> see the IP addresses of your users (and their associated handle). If you want
> to avoid this, you will need to host your own handle resolver. If you are a
> PDS self-hoster, you can use your PDS's URL here. If you rely on Bluesky's
> handle resolver, you are required to inform your users that their IP addresses
> will be shared with Bluesky in your app's privacy policy.
The `oauthClient` is now configured to communicate with Bluesky's Authorization.
We can now initialize it in order to detect if the user is already
authenticated. Replace the `// TO BE CONTINUED` comment with the following code:
> Using Bluesky-hosted services for handle resolution (eg, the `bsky.social`
> endpoint) will leak both user IP addresses and handle identifier to Bluesky,
> a third party. While Bluesky has a declared privacy policy, both developers
> and users of applications need to be informed of and aware of the privacy
> implications of this arrangement. Application developers are encouraged to
> improve user privacy by operating their own handle resolution service when
> possible. If you are a PDS self-hoster, you can use your PDS's URL for
> `handleResolver`.
The `oauthClient` is now configured to communicate with the user's
Authorization Service. You can now initialize it in order to detect if the user
is already authenticated. Replace the `// TO BE CONTINUED` comment with the
following code:

```typescript
const result = await oauthClient.init()
Expand All @@ -212,7 +213,7 @@ the `// TO BE CONTINUED` comment with the following code:

```typescript
if (!agent) {
const handle = prompt('Enter your Bluesky handle to authenticate')
const handle = prompt('Enter your atproto handle to authenticate')
if (!handle) throw new Error('Authentication process canceled by the user')

const url = await oauthClient.authorize(handle)
Expand Down
23 changes: 13 additions & 10 deletions packages/oauth/oauth-client-browser/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# ATPROTO OAuth Client for the Browser
# atproto OAuth Client for the Browser

This package provides an OAuth bases `@atproto/api` agent interface for the
browser. It implements all the OAuth features required by [ATPROTO] (PKCE, DPoP,
Expand Down Expand Up @@ -93,11 +93,14 @@ backend service must be provided.

> [!CAUTION]
>
> Not using a handle resolver service hosted by you will leak the user's IP
> address (and associated ATPROTO handle) to any service you rely on to perform
> the resolution. This is a privacy concern, that you should be aware of, and
> that you **must** warn your users about. Bluesky declines any responsibility
> in case of misusage of the handle resolver service.
> Using Bluesky-hosted services for handle resolution (eg, the `bsky.social`
> endpoint) will leak both user IP addresses and handle identifiers to Bluesky,
> a third party. While Bluesky has a declared privacy policy, both developers
> and users of applications need to be informed and aware of the privacy
> implications of this arrangement. Application developers are encouraged to
> improve user privacy by operating their own handle resolution service when
> possible. If you are a PDS self-hoster, you can use your PDS's URL for
> `handleResolver`.
If a `string` or `URL` object is used as `handleResolver`, the library will
expect this value to be the URL of a service running the
Expand Down Expand Up @@ -146,7 +149,7 @@ following optional configuration options:
response is returned to the client. Defaults to `fragment`.

- `plcDirectoryUrl`: The URL of the PLC directory. This will typically not be
needed unless you run an entire ATPROTO stack locally. Defaults to
needed unless you run an entire atproto stack locally. Defaults to
`https://plc.directory`.

## Usage
Expand Down Expand Up @@ -183,8 +186,8 @@ In order to initiate an OAuth flow, we must fist determine which PDS the
authentication flow will be initiated from. This means that the user must
provide one of the following information:

- The user's ATPROTO handle
- The user's ATPROTO DID
- The user's handle
- The user's DID
- A PDS/Entryway URL

Using that information, the OAuthClient will resolve all the needed information
Expand Down Expand Up @@ -282,7 +285,7 @@ The `client_id` will then be something like
There is however a special case for loopback clients. A loopback client is a
client that runs on `localhost`. In this case, the OAuth server will not be able
to fetch the `client_metadata` object because `localhost` is not accessible from
the outside. To work around this, ATPROTO OAuth server are required to support
the outside. To work around this, atproto OAuth servers are required to support
this case by providing an hard coded `client_metadata` object for the client.

This has several restrictions:
Expand Down
5 changes: 3 additions & 2 deletions packages/oauth/oauth-client-node/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# ATPROTO OAuth Client for NodeJS
# atproto OAuth Client for NodeJS

This package implements all the OAuth features required by [ATPROTO] (PKCE,
etc.) to run in a NodeJS based environment (Election APP or Backend).
etc.) to run in a NodeJS based environment such as desktop apps built with
Electron or traditional web app backends built with frameworks like Express.

## Setup

Expand Down

0 comments on commit 7436874

Please sign in to comment.