Before September 2020, AWS Amplify, which consists of JavaScript libraries and tools to enable fast development and deployment of mobile and front-end web applications powered by AWS (Authentication, Storage, GraphQL and REST APIs, etc), was not supported on the server-side.
Amplify's awesome libraries could only be used in client side JavaScript and therefore server-side rendered JavaScript frameworks such as NextJS could not benefit from actions such as getting authentication status of users and making protected API calls on the server. As such, authentication-based actions and protected API calls which could have been effectively done on the server had to be delayed and moved onto the client-side posing security risks in web clients. So the announcement of server-side support for AWS Amplify came as great joy for users of the library.
Ih this article I will explain how to enable server-side support for an AWS Amplify app and show how to access the Amplify's ‘Auth’ and ‘API’ objects on the server-side in NextJS.
In a NextJS app using Amplify only in the client side, Amplify is configured in the _app.js as shown below:
import {Amplify} from 'aws-amplify'
import config from '../src/aws-export'
// Now configure Amplify
Amplify.configure({...config})
To enable Amplify on the server-side, just add ‘ssr: true’ to the last line:
Amplify.configure({...config, ssr: true})
In NextJS apps, code within getInitialProps, getServerSideProps and API routes (pages/api/*) are executed on the server. Server-side support introduces the new withSSRContext API through which you gain access to the Auth and API objects. The code below illustrates how to access these objects in a getServerSideProps and in a NextJS API route.
import {withSSRContext} from 'aws-amplify'
import {createStock} from '../src/graphql/mutations'
export async function getServerSideProps(context) {
const { Auth, API } = withSSRContext(context)
let is_authenticated = false
try {
const user = await Auth.currentAuthenticatedUser()
// This is an authenticated user
is_authenticated = true
} catch (err) {
console.log(err, 'User is not authenticated')
}
if (is_authenticated){
// Time to make some authenticated API calls
try {
await API.graphql({
query: createStock,
variables: {
input: {
id: 'xxx',
stockValue: 100
}
},
authMode: 'AMAZON_COGNITO_USER_POOLS'
})
} catch (err) {
console.log(err)
}
}
return {
props: { // will be passed to the page component as props
authenticated: is_authenticated
},
}
}
The same approach can be applied in your NextSJ API routes by getting Amplify context object from the API route's req object.
import {withSSRContext} from 'aws-amplify'
import {createStock} from '../src/graphql/mutations'
export default async(req, res) => {
const { API, Auth } = withSSRContext({ req })
let is_authenticated = false
try {
const user = await Auth.currentAuthenticatedUser()
// This is an authenticated user
is_authenticated = true
} catch (err) {
console.log(err, 'User is not authenticated')
}
if (is_authenticated){
if (req.method === 'POST'){
...
}
}
Conclusion
I have shown how to enable AWS Amplify support on the server-side in NextJS and NodeJS applications. Let me know in the comments section below if you have any questions.
Written by: