Open alexwhb opened 3 months ago
Hi @alexwhb, I assume you've previously defined the variables like restAuth
you're passing to create the backend.
Instead of fetching the needed variables like backend. restAuth
, can you try directly using restAuth
?
Could you share the full snippet with definitions for restAuth
and if possible other variables so we can better assist you?
@phani-srikar Absolutely.
restAuth is defined in functions/rest-auth the resource.ts looks like this:
import {defineFunction} from "@aws-amplify/backend";
export const restAuth = defineFunction( )
I'm just looking up a sessionID in my dynomo table to validate it. Note data client is just the Amplify graphQL client. Also note, while this function is defined, I've never actually run it because of that deployment issue when I try to connect it to my REST API. So my implementation is a best effort first attempt. Probably some modification will be needed. and the handler.ts looks like this:
import {dataClient} from "../../utils/data-client";
export type SessionInfo = {
userId: string;
createdAt: string;
sessionId: string; // this is the userId
} | undefined
// Function to look up SessionID in the Sessions table
async function lookupSessionID(sessionID: string): Promise<SessionInfo | null> {
const {data, errors} = await dataClient.models.Session.get({id: sessionID})
if (errors) {
throw new Error(errors.join(','))
}
// const session = await getSession(sessionID)
console.log(JSON.stringify(data), data?.userSessionsId, sessionID)
if (data == null || data.userSessionsId == null) {
throw new Error("Invalid session")
}
return {
userId: data.userSessionsId,
sessionId: data.id,
createdAt: data.createdAt,
};
}
export const handler = async (
event: any
) => {
console.log(event)
const sessionInfo = await lookupSessionID(event.authorizationToken)
console.log(`RESPONSE: ${JSON.stringify(sessionInfo, null, 2)}`);
return {
principalId: 'user',
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: sessionInfo == null ? 'Deny': 'Allow',
Resource: event.methodArn
}],
},
context: sessionInfo // this is our session info to pass to the rest handler
};
};
Here's a slightly abbreviated version of my schema:
const schema = a.schema({
Session: a.model({
user: a.belongsTo('User'),
appCode: a.string().required()
}).authorization([a.allow.public('iam')]),
User: a.model({
entitlements: a.hasMany('Entitlement'),
sessions: a.hasMany('Session'),
credits: a.integer(),
}).authorization([a.allow.public('iam')]),
Entitlement: a
.model({
user: a.belongsTo('User'),
productId: a.string().required(),
squareImageUrl: a.string().required(),
bookId: a.string().required(),
}).authorization([a.allow.public('iam')]),
})
.authorization([
a.allow.resource(loginRestHandler),
a.allow.resource(restAuth).to(['query']),
a.allow.resource(getEntitlements),
]);
export type Schema = ClientSchema<typeof schema>;
export const data = defineData({
schema,
name: "MyLibrary",
functions: {},
authorizationModes: {
defaultAuthorizationMode: 'iam',
},
});
Let me know if any other details would be helpful. Happy to provide them.
Instead of fetching the needed variables like backend. restAuth, can you try directly using restAuth?
Can you try this and let us know if it works?
@phani-srikar Thanks for getting back to me. Do you mean like this:
# where rest auth is just my imported defineFunction()
const addToLibrary = account.addResource('add-to-library', {
defaultMethodOptions: {authorizationType: AuthorizationType.CUSTOM, authorizer: restAuth}
})
or are you meaning like this:
const restAuthMod = new TokenAuthorizer(apiGatewayStack, 'user-Auth', {
handler: restAuth
});
then using restAuthMod
here:
const addToLibrary = account.addResource('add-to-library', {
defaultMethodOptions: {authorizationType: AuthorizationType.CUSTOM, authorizer: restAuthMod}
})
Or something else?
I tried the above two and unless I'm missing something the types are not appropriate.
Hi @alexwhb apologies for the delay. Could you share more of your code or provide a minimal sample repo that reproduces the issue so that we can troubleshoot this on our end?
I tried to use the code you shared but I'm missing some things like:
myRestHandler,
getEntitlements,
loginRestHandler,
addEntitlementsByCreditRest
UPDATE: I was able to reproduce the issue on this repo and branch:
https://github.com/chrisbonifacio/amplify-gen2-app/tree/circular-dep-error
We will report back once we've found a solution
@chrisbonifacio Awesome!!! You're the best. Thanks for looking into this. My temporary solution is to just wrap all my lambdas in auth middleware, but it'll be super nice to have auth decoupled.
@chrisbonifacio were you ever able to find a solution to this one? :)
@alexwhb could you explain what you meant here by wrapping them all in auth middleware?
@LukaASoban ya I just use the middy library which allows you to wrap your handlers in different middleware. I use that for authentication as well as input validation. The downside to this is the handlers themselves are doing the authentication every single request, so it's certainly not as efficient since there's no caching.
@LukaASoban can you try this workaround to re-arrange your resources b/w stacks - https://github.com/aws-amplify/amplify-backend/issues/1552#issuecomment-2138331128
Amplify CLI Version
System: OS: macOS 14.3.1 CPU: (16) arm64 Apple M3 Max Memory: 446.17 MB / 48.00 GB Shell: /bin/zsh Binaries: Node: 18.18.0 - ~/.nvm/versions/node/v18.18.0/bin/node Yarn: undefined - undefined npm: 9.8.1 - ~/.nvm/versions/node/v18.18.0/bin/npm pnpm: undefined - undefined NPM Packages: @aws-amplify/backend: 0.13.0-beta.9 @aws-amplify/backend-cli: 0.12.0-beta.10 aws-amplify: 6.0.21 aws-cdk: 2.133.0 aws-cdk-lib: 2.133.0 typescript: 5.4.2 AWS environment variables: AWS_STS_REGIONAL_ENDPOINTS = regional AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1 AWS_SDK_LOAD_CONFIG = 1 No CDK environment variables%
Question
I'm attempting to setup a REST API but am struggling with setting up my auth system. I'm trying to do a very simple lambda auth function that just checks a auth token header. with restAuth
I'm thinking this is likely something I'm doing wrong... not a bug with Amplify, though I'm not totally sure.
but whenever I try deploying this I get this error:
I know it's definitely related to the restAuth code, because as soon as I comment that out it deploys without issue. What could I be doing wrong?
Here's what my backend ts file looks like: