How to query for a signed in user's data in Graphql and AWS Cognito

Viewed 417

I am trying to query for a user's specific data using AWS Cognito, Appsync, and Graphql. Before I changed my Schema rules to include @auth, I was able to access all data from all users, but that is not what I want. However, when I query for data using Graphql, I am getting an auauthorized error. errorType: "Unauthorized", message: "Not Authorized to access listMembers on type Query", … }

// Old Schema.graphql
type Member {
  id: ID!,
  name: String,
  owner: String
}
// New Schema.graphql
type Member
  @model
  @auth(rules: [{ allow: owner }, { allow: private, operations: [read] }]) {
  id: ID!
  name: String
  owner: String
}

In my Members.js component, I call for the list of members and ensure I have set that the owner property is available, but I still get the unauthorized error. Additionally, when I go into AWS AppSync Console and try to query for a list of members, I get the same error.

enter image description here

I know I have members in my DynamoDB, because they are present, but when I query for them, that's when I get that error.

enter image description here

This is what my Member.js component looks like:

// Members.js

import { useState, useEffect } from 'react'
import { API, Auth } from 'aws-amplify'
import { listMembers } from '../../graphql/queries'

const [members, updateMembers] = useState([])
const [myMembers, updateMyMembers] = useState([])

export const Members = () => {

  /* fetch member's when component loads */
  useEffect(() => {
    fetchMembers()
  }, [])

  async function fetchMembers() {
    /* query the API, ask for 100 items */
    let postData = await API.graphql({
      query: { query: listMemberes, variables: { limit: 100 }},
      variables: { limit: 100 },
    })

    let membersArray = postData.data.listMembers.items
    updateLoading(false)

    /* update the members array in the local state */
    setMemberState(membersArray)
  }

  async function setMemberState(membersArray) {
    const user = await Auth.currentAuthenticatedUser()
    const myMemberData = membersArray.filter((p) => p.owner === user.username)
    console.log('membersArray:', membersArray)
    updateMyMembers(myMemberData)
    updateMembers(membersArray)
  }

}

2 Answers

You have to add 2 additional rules:

type Member
  @model
  @auth(
    rules: [
      { allow: owner }
      { allow: public, operations: [create, read, update, delete] } // New
      { allow: private, operations: [create, read, update, delete] } // New
    ]
  ) {
  id: ID!
  name: String
  owner: String
}

Probably your default Auth method is API_KEY

You can see this in aws-export.js file.

"aws_appsync_authenticationType": "API_KEY",

So you have to change your request a little bit so that it takes the cognito user with which you are logged in:

let postData = await API.graphql({
  query: { query: listMemberes, variables: { limit: 100 }},
  variables: { limit: 100 },
  authMode: 'AMAZON_COGNITO_USER_POOLS'

})

Source: https://docs.amplify.aws/lib/graphqlapi/query-data/q/platform/js/#simple-query

Related