Deployed NextJS app on AWS Amplify
I am getting untrust host in my CloudWatch logs.
Can someone help?
[next-auth][error][UNTRUST_HOST_ERROR]
URL: https://master.dtzbr8sfj0q7k.amplifyapp.com/
I have added this domain in my Cognito allowed callbacks.
package.json
"next": "13.0.7",
"next-auth": "^4.18.6",
Build Settings
version: 1
applications:
- frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- npm run build
- COGNITO_CLIENT_ID=${COGNITO_CLIENT_ID}
- COGNITO_CLIENT_SECRET=${COGNITO_CLIENT_SECRET}
- COGNITO_DOMAIN=${COGNITO_DOMAIN}
- JWT_SECRET=${JWT_SECRET}
- NEXTAUTH_URL=${NEXTAUTH_URL}
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
appRoot: client
/pages/api/[...nextauth].js
import NextAuth from "next-auth/next";
function CognitoProvider(options) {
return {
id: "cognito",
name: "Cognito",
type: "oauth",
wellKnown: `${options.issuer}/.well-known/openid-configuration`,
idToken: true,
profile(profile) {
return {
id: profile.sub,
name: profile.name,
email: profile.email,
image: profile.picture,
};
},
options,
};
}
export default NextAuth({
providers: [
CognitoProvider({
clientId: process.env.COGNITO_CLIENT_ID,
clientSecret: process.env.COGNITO_CLIENT_SECRET,
issuer: process.env.COGNITO_DOMAIN,
}),
],
secret: process.env.JWT_SECRET,
callbacks: {
jwt({ token, account, profile }) {
if (account) {
console.log("Account exists");
// modify token
token.role = profile["cognito:groups"];
}
return token;
},
session({ session, token }) {
if (session.user) {
// modify session
session.user.roles = token.role;
}
return session;
},
},
});
/index.js
import Head from "next/head";
import App from "../components/App/App";
import { useSession, signIn, signOut } from "next-auth/react";
export default function Home() {
const { data: session } = useSession();
if (session) {
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<App />
</>
);
}
return (
<>
Not signed in <br />
<button
onClick={() => {
e.preventDefault();
signIn("cognito", {
callbackUrl: process.env.NEXTAUTH_URL,
});
}}
>
Sign in
</button>
</>
);
}
Any Help would be appreciated
I had the same problem today and I found this solution that worked for me:
I had to edit the amplify.yml in build settings and set env variables inside a .env file as below:
version: 1
frontend:
phases:
preBuild:
commands:
- npm ci
build:
commands:
- echo "NEXTAUTH_URL=$NEXTAUTH_URL" >> .env
- echo "JWT_SECRET=$JWT_SECRET" >> .env
- npm run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
I had to do it for all of my environment variables to allow my Next.js application to access them.
Hope it helped.
Make sure you have configured NEXTAUTH_URL environment variable correctly on AWS Amplify.
I checked your website, and I see this error:
CLIENT_FETCH_ERROR
On NextAuth.js documentation,
Here's a similar case:
How to solve client fetch error for next-auth authentication
Update
Sorry for the late reply. These links might give you a little more information about the issue.
Similiar Case
Environment Variables User Guide on AWS Amplify
Related
NextJs Application is working perfectly fine locally but after pushing the fronted to AWS I'm getting the run time error, No Credentials in callback.js api
No Build time error, so I assume aws-exports.js file is built correctly during the build but I don't know if it is built with the required details like API key on AWS.
I'm using API key authentication by default. I'm not using amplify add auth because I've a requirement to use custom auth. I know amplify auth is the recommend way but I still need to use my custom method.
I have already tried multiple suggestions like disable Analytics: true as suggested in couple of other discussions but none of them worked for me. Build my project multiple times from scratch by re-installing all the dependencies but no luck.
callback.js API
import { API, graphqlOperation } from 'aws-amplify';
import {getAuth} from "../../../../src/graphql/queries"
import {createAuth} from "../../../../src/graphql/mutations"
export default async function callback(req, res) {
const record = await API.graphql(graphqlOperation(getAuth, {emailId: "abc#gmail.com"}))
res.status(200).json({ record });
}
aws-exports.js
/* eslint-disable */
// WARNING: DO NOT EDIT. This file is automatically generated by AWS Amplify. It will be overwritten.
const awsmobile = {
"aws_project_region": "us-east-1",
"aws_appsync_graphqlEndpoint": "https://dummyUrl.appsync-api.us-east-1.amazonaws.com/graphql",
"aws_appsync_region": "us-east-1",
"aws_appsync_authenticationType": "API_KEY",
"aws_appsync_apiKey": "da2-************"
};
export default awsmobile;
_app.js
import {Amplify} from 'aws-amplify';
import config from "../aws-exports"
Amplify.configure(config)
function MyApp({ Component, pageProps: { session, ...pageProps } }) {
// App logic
})
GraphQL Schema
type Auth #model #auth(rules: [{ allow: public }]) {
emailId: ID! #primaryKey
name: String
screen_name: String
profile_img: String
userSession: String
tokenType: String
accessToken: String
accessSecret: String
refreshToken: String
accessScope: String
}
Package.json
"dependencies": {
"#emoji-mart/data": "^1.0.6",
"#emoji-mart/react": "^1.0.1",
"aes256": "^1.1.0",
"aws-amplify": "^4.3.37",
"emoji-mart": "^5.2.2",
"formidable": "^2.0.1",
"js-cookie": "^3.0.1",
"next": "12.3.1",
"react": "18.2.0",
"react-datepicker": "^4.8.0",
"react-dom": "18.2.0",
},
Amplify.yml
version: 1
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- yarn install
build:
commands:
- yarn run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- node_modules/**/*
Edited
I've found how the server side process work with amplify and graphql. Please refer to this. On the server side, you need to pass the API KEY explicitly into the graphql request as that page writes.
==========
I'm using appsync, but appsync pure directives. So just let me provide the reference below. Please confirm the rule follows this way.
{ allow: public, provider: apiKey }
I just finished my project in Strapi and deployed in AWS, when I run my Public ipv4 :1337 says: 'server is running successully' but when I want to log in admin panel just spinning and not showing panel.
server.js
module.exports = ({ env }) => ({
host: env('HOST', '0.0.0.0'),
port: env.int('PORT', 1337),
cron: { enabled: true},
url: env('URL', 'http://localhost'),
admin: {
auth: {
secret: env('ADMIN_JWT_SECRET', 'MY_JWT_SECRET'),
},
},
});
I have done plenty of tests and research on this, but I simply cannot figure it out. I have a function that works perfectly fine when running locally (no errors), but fails when deployed as AWS lambda.
I created a simple example that recreates it:
URL LOCAL: http://localhost:3000/flagTest/visible (this works fine ✅)
URL DEPLOYED AS LAMBDA: https://www.publicfaq.com/flagTest/visible (the Toggle button doesn't work ❌)
FILE: /pages/flagTest/[tid].js (on a barebone NextJS installation)
import React from 'react'
class FlagTest extends React.Component {
static async getInitialProps({ query }) {
return { visible: query.tid }
}
constructor(){
super();
this.state = {
showFlag:false,
}
}
componentWillMount(){
this.setState({ showFlag: this.props.visible === 'visible' });
}
handleToggle =()=> {
this.setState({
showFlag:!this.state.showFlag
});
}
render() {
return (
<div>
<h1>Flag: {this.state.showFlag ? '🏁' : ''} </h1>
<button className='list_toggle' onClick={this.handleToggle}>
{this.state.showFlag ? 'Hide Flag': 'Show Flag'}
</button>
<hr/>
Props:
<pre>
{JSON.stringify(this.props, null, 2)}
</pre>
State:
<pre>
{JSON.stringify(this.state, null, 2)}
</pre>
</div>
);
}
}
export default FlagTest
Note: I do need to use getInitialProps because I'm planning to use it in a more complex case (API Fetching by id), didn't included it here because is not directly related with this problem.
This is my Serverless YML
service: A123-serverless
provider:
name: aws
runtime: nodejs8.10
stage: ${self:custom.secrets.NODE_ENV}
region: us-west-2
environment:
NODE_ENV: ${self:custom.secrets.NODE_ENV}
functions:
server:
handler: index.server
events:
- http: ANY /
- http: ANY /{proxy+}
plugins:
- serverless-apigw-binary
- serverless-domain-manager
custom:
secrets: ${file(secrets.json)}
apigwBinary:
types:
- '*/*'
customDomain:
domainName: ${self:custom.secrets.DOMAIN}
basePath: ''
stage: ${self:custom.secrets.NODE_ENV}
createRoute53Record: true
endpointType: 'regional'
Thanks!
I found the answer to my problem, posting it here, hopefully will help someone with the same problem:
The Problem was that I was using "query" to extract the 'id', It was working fine in local, but in the Server Side using Express you need to pass that as a parameter like this:
server.get("/q/:id", (req, res) => {
return app.render(req, res, "/q/_tid", { id: req.params.id });
});
Then on the React component you can catch it and use it getInitial Props as req.params.id
static async getInitialProps({ req }) {
myId = req.params.id
}
I am trying to deploy a meteor app to an AWS server, but am getting this message:
Started TaskList: Configuring App
[52.41.84.125] - Pushing the Startup Script
nodemiral:sess:52.41.84.125 copy file - src: /
Users/Olivia/.nvm/versions/node/v7.8.0/lib/node_modules/mup/lib/modules/meteor/assets/templates/start.sh, dest: /opt/CanDu/config/start.sh, vars: {"appName":"CanDu","useLocalMongo":0,"port":80,"bind":"0.0.0.0","logConfig":{"opts":{"max-size":"100m","max-file":10}},"docker":{"image":"abernix/meteord:base","imageFrontendServer":"meteorhacks/mup-frontend-server","imagePort":80},"nginxClientUploadLimit":"10M"} +0ms
[52.41.84.125] x Pushing the Startup Script: FAILED Failure
Previously I had been able to deploy using mup, but now I am getting this message. The only major thing I've changed is the Python path in my .noderc. I am also able to SSH into my amazon server directly from the terminal. My mup file is:
module.exports = {
servers: {
one: {
host: '##.##.##.###',
username: 'ec2-user',
pem: '/Users/Olivia/.ssh/oz-pair.pem'
// password:
// or leave blank for authenticate from ssh-agent
}}meteor: {
name: 'CanDu',
path: '/Users/Olivia/repos/bene_candu_v2',
servers: {
one: {}
},
buildOptions: {
serverOnly: true,
mobileSettings: {
public: {
"astronomer": {
"appId": "<key>",
"disableUserTracking": false,
"disableRouteTracking": false,
"disableMethodTracking": false
},
"googleMaps": "<key>",
"facebook":{
"permissions":["email","public_profile","user_friends"]
}
},
},
},
env: {
ROOT_URL: 'http://ec2-##-##-##-###.us-west-2.compute.amazonaws.com',
MONGO_URL: 'mongodb://. . . "
},
/*ssl: {
crt: '/opt/keys/server.crt', // this is a bundle of certificates
key: '/opt/keys/server.key', // this is the private key of the certificate
port: 443, // 443 is the default value and it's the standard HTTPS port
upload: false
},*/
docker: {
image: 'abernix/meteord:base'
},
deployCheckWaitTime: 60
}
};
And I have checked to make sure there are no trailing commas, and have tried increasing the wait time. etc. The error message I'm getting is pretty unhelpful. Does anyone have any insight? Thank you so much!
I've managed to deploy a simple todo app unto AWS with S3 using this site
http://emberigniter.com/deploy-ember-cli-app-amazon-s3-linux-ssh-rsync/
However, when I attempt to do this ( Deploying with SSH and Rsync ) according to the tutorial, I run into the following error:
gzipping **/*.{js,css,json,ico,map,xml,txt,svg,eot,ttf,woff,woff2}
ignoring null
✔ assets/ember-user-app-d41d8cd98f00b204e9800998ecf8427e.css
✔ assets/vendor-d41d8cd98f00b204e9800998ecf8427e.css
✔ assets/ember-user-app-45a9825ab0116a8007bb48645b09f060.js
✔ crossdomain.xml
✔ robots.txt
✔ assets/vendor-d008595752c8e859a04200ceb9a77874.js
gzipped 6 files ok
|
+- upload
| |
| +- rsync
- Uploading using rsync...
- Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at /BuildRoot/Library/Caches/com.apple.xbs/Sources/rsync/rsync-47/rsync/io.c(453) [sender=2.6.9]
The following is my config/deploy.js
module.exports = function(deployTarget) {
var ENV = {
build: {
environment: deployTarget
},
's3-index': {
accessKeyId: "<myKeyID>",
secretAccessKey: "<mySecret>",
bucket: "emberjsft",
region: "ap-southeast-1",
allowOverwrite: true
},
's3': {
accessKeyId: "<myKeyID>",
secretAccessKey: "<mySecret>",
bucket: "emberjsft",
region: "ap-southeast-1"
},
'ssh-index': {
remoteDir: "/var/www/",
username: "ec2-user",
host: "ec2-<elastic-ip>.ap-southeast-1.compute.amazonaws.com",
privateKeyFile: "/Users/imac/MY_AWS_PEMFILE.pem",
allowOverwrite: true
},
rsync: {
dest: "/var/www/",
username: "ec2-user",
host: "ec2-<elastic-ip>.ap-southeast-1.compute.amazonaws.com",
delete: false
}
// include other plugin configuration that applies to all deploy targets here
};
if (deployTarget === 'development') {
ENV.build.environment = 'development';
// configure other plugins for development deploy target here
}
if (deployTarget === 'staging') {
ENV.build.environment = 'production';
// configure other plugins for staging deploy target here
}
if (deployTarget === 'production') {
ENV.build.environment = 'production';
// configure other plugins for production deploy target here
}
// Note: if you need to build some configuration asynchronously, you can return
// a promise that resolves with the ENV object instead of returning the
// ENV object synchronously.
return ENV;
};
How should I resolve this issue?
Thanks
I've just spent the last hour fighting the same issue as you. I was able to kind of fix it by using ssh-add /home/user/.ssh/example-key.pem and removing privateKeyFile.
I still get a error thrown after the transfer ends, but can confirm all files successfully transferred to my EC2 box despite the error..
deploy.js
module.exports = function (deployTarget) {
var ENV = {
build: {
environment: deployTarget
},
'ssh-index': {
remoteDir: "/var/www/",
username: "ubuntu",
host: "52.xx.xx.xx",
allowOverwrite: true
},
rsync: {
host: "ubuntu#52.xx.xx.xx",
dest: "/var/www/",
recursive: true,
delete: true
}
};
return ENV;
};
In your deploy.js file you need to place your information for accessKeyId. You left "" in the place of accessKeyId. You need to put your information there. Same for secretAccessKey, acessKeyId, plus your host , you need to put your elastic-ip address.
myKeyID and mySecret shall be present in a .env file and then accessed here by process.env.myKeyID , process.env.mySecret
Not a good practice to hard-code the Keys in deploy.js file.
Best practise would be read it using Consul