Previously, I posted a serverless web app hands-on article "Using AppSync on the front and back ends". Here, as a matter of course, "API Key" was used as the authentication mode. Authentication with this API Key is good for beginners to use it first or as a simple prototype, but considering the safety and the trouble of updating with a maximum expiration date of 365 days, Other authentication modes should be adopted if possible. You can see the key ... I will definitely forget to update the key after 365 days.
In addition to API Key, AppSync supports the following authentication modes.
** What is IAM ** It is a mechanism to control the range and access method of accessing AWS resources.
** What is Cognito User Pool ** It is a mechanism to provide application user management (sign-up and sign-in status).
** What is OpenID Connect ** I'm not familiar with it because I've never used it. (Like Cognito, it feels like logging in and authenticating using the issued token?)
AppSync supported multiple authentication modes in May 2019. https://aws.amazon.com/jp/about-aws/whats-new/2019/05/aws-appsync-now-supports-configuring-multiple-authorization-type/
This makes it possible to authenticate with Cognito on the front end (client side) and IAM on the back end (server side).
By using Amplify, it has become possible to quickly realize the construction of AppSync with Cognito authentication and the implementation of using it from the front end (web application).
From there in this article, Added IAM as an authentication provider for use on the backend, I would like to write about actually hitting (calling the API) from Lambda (Python).
AWS Console> AWS AppSync> Select the desired API> Settings There is an item called "Additional Authentication Provider" at the bottom, so press the New button. Select "AWS Identify and Access Management (IAM)" from the authentication mode combo box on the "Set additional authentication provider" pop-up screen and press the "Send" button. Confirm that "AWS Identify and Access Management (IAM)" is added to "Additional Authentication Provider" in the settings, and press the "Save" button at the bottom. (* Don't forget!)
When using multiple authentication modes, it is necessary to add to the schema. You can specify in detail what you can do in which authentication mode for each root type such as Query, Mutation, Subscription, and user-defined function fields and object types in it. (* Cannot be specified for input type)
By default, nothing is specified, which means that only the primary authentication mode is allowed, and the added authentication mode is not allowed. You can specify the authentication mode by making the following markings.
@aws_api_key
@aws_iam
@aws_oidc
@aws_cognito_user_pools
See this developer guide for more details. (Rather, everything is written here) https://docs.aws.amazon.com/ja_jp/appsync/latest/devguide/appsync-dg%20.pdf
AWS Console> AWS AppSync> Select the desired API> Schema After editing the graphql schema here, click the "Save Schema" button.
Here are some examples of schemas before editing (Before.graphql) and after editing (After.graphql).
Before.graphql
type Mutation {
createSampleAppsyncTable(input: CreateSampleAppsyncTableInput!): SampleAppsyncTable
updateSampleAppsyncTable(input: UpdateSampleAppsyncTableInput!): SampleAppsyncTable
deleteSampleAppsyncTable(input: DeleteSampleAppsyncTableInput!): SampleAppsyncTable
}
type Query {
getSampleAppsyncTable(group: String!, path: String!): SampleAppsyncTable
listSampleAppsyncTables(filter: TableSampleAppsyncTableFilterInput, limit: Int, nextToken: String): SampleAppsyncTableConnection
}
type SampleAppsyncTable {
group: String!
path: String!
}
After.graphql
type Mutation {
createSampleAppsyncTable(input: CreateSampleAppsyncTableInput!): SampleAppsyncTable
@aws_cognito_user_pools @aws_iam
updateSampleAppsyncTable(input: UpdateSampleAppsyncTableInput!): SampleAppsyncTable
@aws_iam
deleteSampleAppsyncTable(input: DeleteSampleAppsyncTableInput!): SampleAppsyncTable
}
type Query @aws_cognito_user_pools {
getSampleAppsyncTable(group: String!, path: String!): SampleAppsyncTable
listSampleAppsyncTables(filter: TableSampleAppsyncTableFilterInput, limit: Int, nextToken: String): SampleAppsyncTableConnection
}
type SampleAppsyncTable @aws_cognito_user_pools @aws_iam {
group: String!
path: String!
}
In this example, it is specified as follows. Mutation.create: Cognito and IAM Mutation.update: IAM only Mutation.delete: Cognito only (not specified = primary) Query: get and list are Cognito only
As I thought so far, it seems good to design the primary authentication to be IAM instead of Cognito and give Cognito permission only for what is needed on the client side.
It is an implementation for hitting AppSync with IAM authentication permission with Python of Lambda.
sample_graphql_with_iam.py
import requests
from requests_aws4auth import AWS4Auth
AWS_REGION = os.environ["AWS_REGION"]
AWS_ACCESS_KEY_ID = os.environ["AWS_ACCESS_KEY_ID"]
AWS_SECRET_ACCESS_KEY = os.environ["AWS_SECRET_ACCESS_KEY"]
AWS_SESSION_TOKEN = os.environ["AWS_SESSION_TOKEN"]
ENDPOINT = "https://{0}.{1}.{2}.amazonaws.com/{3}".format("xxxxxxxxxxxxxxxxxxxxxx", "appsync-api", AWS_REGION, "graphql")
AUTH = AWS4Auth(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION, 'appsync', session_token=AWS_SESSION_TOKEN)
def apiCreateTable(group, path):
try:
body_json = {"query":
"""
mutation create {{
createSampleAppsyncTable(input:{{
group: \"{0}\"
path: \"{1}\"
}}){{
group path
}}
}}
""".format(group, path)
}
body = json.dumps(body_json)
response = requests.request("POST", ENDPOINT, auth=AUTH, data=body, headers={})
except Exception as e:
logger.exception(e)
raise e
Add the AppSync policy to the Lambda IAM role you want to run. All you have to do is attach AWSAppSyncAdministrator. (* I think it's better to write an inline policy to allow only the target API, not the entire AppSync, but I don't know how to write it. Can anyone please tell me!)
You can hit it from the front, and you can hit it from the back. If you wait in front of you to be hit from behind, it will feel cool. (* Subscription story) Both front and back are boring with Cognito, so I'm using IAM behind. (* Authentication story)
As a result of talking about JAWS UG Hamamatsu (Uncle Amplify), I came up with the idea of writing this article.
In LT at the end of last year, I used this kind of illustration. (Image of waiting in front of being hit from behind)
I would like to continue to capture AppSync, which seems to be useful for various purposes and is worth developing!