Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(apollo): Add details about authorization modes to Apollo AppSync README #2912

Merged
merged 5 commits into from
Sep 23, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 75 additions & 1 deletion apollo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,86 @@ For applications using `apollo-appsync-amplify`, you can connect directly to you
val connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))

val apolloClient = ApolloClient.Builder()
.appSync(connector.endpoint, connect.apiKeyAuthorizer())
.appSync(connector.endpoint, connector.apiKeyAuthorizer())
.build()
```

Once you have constructed the Apollo client you can use it as normal for queries, mutations, and subscriptions to AppSync.

## Authorization Modes

AWS AppSync supports [five different authorization modes](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html):

- API Key
- AWS Lambda Function
- AWS IAM Permissions
- OIDC Provider
- Amazon Cognito User Pool

The Apollo AppSync Extensions libraries expose three authorizer types to support these different authorization modes.

### ApiKeyAuthorizer

An `ApiKeyAuthorizer` is used to provide a key for [API Key authorization](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#api-key-authorization) requests.

This Authorizer can be used with a hardcoded API key, by fetching the key from some source, or reading it from `amplify_outputs.json`:

```kotlin
// Create an authorizer directly with your API key:
val authorizer = ApiKeyAuthorizer("[YOUR_API_KEY")
```
```kotlin
// Create an authorizer that fetches your API key. The fetching function may be called many times,
// and should internally implement an appropriate caching mechanism.
val authorizer = ApiKeyAuthorizer { fetchApiKey() }
```
```kotlin
// Using ApolloAmplifyConnector to read API key from amplify_outputs.json
val connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))
val authorizer = connector.apiKeyAuthorizer()
```

### AuthTokenAuthorizer

An `AuthTokenAuthorizer` sets an authentication header for use with [AWS Lambda](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#aws-lambda-authorization),
[OIDC provider](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#openid-connect-authorization), and
[Amazon Cognito User Pool](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#amazon-cognito-user-pools-authorization)
authorization modes.

Using `ApolloAmplifyConnector` allows you to automatically authorize requests for the signed-in Amplify user, or you can implement the Authorizer's function parameter yourself to provide other types of tokens.

```kotlin
// Provide a token from e.g. an OIDC provider. The fetching function may be called many times,
// and should internally implement an appropriate caching mechanism.
val authorizer = AuthTokenAuthorizer { fetchUserToken() }
```
```kotlin
// Use ApolloAmplifyConnector to get Cognito tokens from Amplify for the signed-in user
val connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))
val authorizer = connector.authTokenAuthorizer()
// or
val authorizer = AuthTokenAuthorizer { ApolloAmplifyConnector.fetchLatestCognitoAuthToken() }
```

### IamAuthorizer

An `IamAuthorizer` is used to provide request signature headers for using [AWS IAM-based authorization](https://docs.aws.amazon.com/appsync/latest/devguide/security-authz.html#aws-iam-authorization).

Using `ApolloAmplifyConnector` is the easiest way to use this authorizer, but you can also implement the signing function yourself, by e.g. delegating to the [AWS Kotlin SDK](https://github.com/awslabs/aws-sdk-kotlin).

```kotlin
// Provide an implementation of the signing function. This function should implement the
// AWS Sig-v4 signing logic and return the authorization headers containing the token and signature.
val authorizer = IamAuthorizer { signRequestAndReturnHeaders(it) }
```
```kotlin
// Use ApolloAmplifyConnector to sign the request
val connector = ApolloAmplifyConnector(context, AmplifyOutputs(R.raw.amplify_outputs))
val authorizer = connector.iamAuthorizer()
// or supply a region to sign via the companion function
val authorizer = IamAuthorizer { ApolloAmplifyConnector.signAppSyncRequest(it, "us-east-1") }
```

## Contributing

- [CONTRIBUTING.md](../CONTRIBUTING.md)
Expand Down
Loading