Skip to content

Instantly share code, notes, and snippets.

@pedropbazzo
Created February 3, 2021 01:44
Show Gist options
  • Save pedropbazzo/6b9dd9c8fb174665a2c3256e9561de57 to your computer and use it in GitHub Desktop.
Save pedropbazzo/6b9dd9c8fb174665a2c3256e9561de57 to your computer and use it in GitHub Desktop.
Para começar, primeiro crie um novo aplicativo Next.js:
npx create-next-app next-authentication
Em seguida, mude para o novo diretório e instale as dependências:
cd next-authentication
npm install aws-amplify @aws-amplify/ui-react emotion
Inicialize um novo projeto Amplify:
amplify init
> Choose defaults when prompted
Se você ainda não instalou e configurou o Amplify CLI, veja este vídeo para uma explicação completa.
Adicione o serviço de autenticação:
amplify add auth
? Do you want to use the default authentication and security configuration? Default configuration
? How do you want users to be able to sign in? Username
? Do you want to configure advanced settings? No, I am done.
Em seguida, implante o serviço de autenticação:
amplify push --y
Ativando Amplify SSR
Para ativar o suporte ao Amplify SSR, abra pages/_app.js e adicione o seguinte na parte superior do arquivo:
import Amplify from 'aws-amplify'
import config from '../src/aws-exports'
Amplify.configure({
...config,
ssr: true
})
🔥 Definindo ssrcomo true é tudo o que você precisa fazer para tornar seu aplicativo Amplify compatível com SSR.
Criação da rota de autenticação / perfil
Em seguida, crie um novo arquivo no diretório de pages denominado profile.js .
Aqui, vamos habilitar a autenticação usando o componente withAuthenticator. Este componente criará um fluxo de autenticação do usuário, permitindo que um usuário se inscreva com MFA e faça login.
Neste arquivo, adicione o seguinte código:
// pages/profile.js
import { useState, useEffect } from 'react'
import { Auth } from 'aws-amplify'
import { withAuthenticator, AmplifySignOut } from '@aws-amplify/ui-react'
function Profile() {
const [user, setUser] = useState(null)
useEffect(() => {
// Acessa a sessão do usuário no cliente
Auth.currentAuthenticatedUser()
.then(user => {
console.log("User: ", user)
setUser(user)
})
.catch(err => setUser(null))
}, [])
return (
<div>
{ user && <h1>Welcome, {user.username}</h1> }
<AmplifySignOut />
</div>
)
}
export default withAuthenticator(Profile)
Por fim, atualize pages/_app.js para adicionar um pouco de navegação entre as páginas:
import '../styles/globals.css'
import Link from 'next/link'
import { css } from 'emotion'
import Amplify from 'aws-amplify'
import config from '../src/aws-exports'
Amplify.configure({
...config,
ssr: true
})
export default function MyApp({ Component, pageProps }) {
return (
<div>
<nav className={navStyle}>
<Link href="/">
<span className={linkStyle}>Home</span>
</Link>
<Link href="/profile">
<span className={linkStyle}>Profile</span>
</Link>
</nav>
<Component {...pageProps} />
</div>
)
}
const linkStyle = css`
margin-right: 20px;
cursor: pointer;
`
const navStyle = css`
display: flex;
`
Opcional — Estilo do componente
Você pode configurar o estilo do componente de autenticação. Por exemplo, para tentar combinar o esquema de cor azul que acompanha o projeto inicial de Next.js, você pode adicionar o seguinte na parte inferior de styles/globals.css :
:root {
--amplify-primary-color: #0083e8;
--amplify-primary-tint: #006ec2;
--amplify-primary-shade: #006ec2;
}
Criar uma conta e fazer login
Agora que a rota de perfil foi criada, vamos testá-la criando uma nova conta e fazendo login.
npm run dev
Clique aqui para obter mais maneiras de personalizar o componente withAuthenticator.
Você deve conseguir navegar para a rota /profile para criar uma conta e fazer login.
Usando a classe Auth diretamente
Se você quer construir seu próprio fluxo de autenticação personalizada, você também pode aproveitar a classe Auth que tem mais de 30 métodos para gerenciar o estado da autenticação do usuário, incluindo métodos, como signUp, confirmSignUp, signIn, e forgotPassword.
Acessando a sessão do usuário em uma rota SSR
Agora que os usuários podem fazer o login, vamos criar uma nova rota para testar o SSR.
Crie uma nova rota chamada /protected.js no diretório de páginas.
Aqui, queremos ter uma rota que autentique o usuário no servidor e retorne uma mensagem de sucesso ou de erro com base no estado de autenticação do usuário.
// pages/protected.js
import { withSSRContext } from 'aws-amplify'
function Protected({ authenticated, username }) {
if (!authenticated) {
return <h1>Not authenticated</h1>
}
return <h1>Hello {username} from SSR route!</h1>
}
export async function getServerSideProps(context) {
const { Auth } = withSSRContext(context)
try {
const user = await Auth.currentAuthenticatedUser()
console.log('user: ', user)
return {
props: {
authenticated: true, username: user.username
}
}
} catch (err) {
return {
props: {
authenticated: false
}
}
}
}
export default Protected
Em seguida, atualize a navegação em pages/_app.js com um link para a nova rota:
<Link href="/protected">
<span className={linkStyle}>Protected route</span>
</Link>
Agora, quando você estiver conectado, perceberá que poderá acessar o usuário autenticado no método getServerSideProps. Você também deve ver o objeto de usuário printado no terminal.
Isso é feito usando a função withSSRContext da biblioteca aws-amplify que retorna o objeto Auth e com isso, chamamos o Auth.currentAuthenticatedUser(). Ao obter acesso à classe Auth dessa maneira, o Amplify lerá automaticamente o objeto de solicitação da requisição (context) e dará a você acesso à sessão do usuário conectado em ambas as rotas de API e também em rotas SSR.
Acessando a sessão do usuário em uma rota de API
Nesta rota de API, queremos acessar a sessão do usuário e retornar null para um usuário que não está autenticado ou o nome de usuário para um usuário que está autenticado.
Para fazer isso, crie um novo arquivo em pages/api chamado check-user.js :
// pages/api/check-user.js
import Amplify, { withSSRContext } from 'aws-amplify'
import config from "../../src/aws-exports.js"
// Configuração necessária para habilitar o Amplify SSR em rotas de API
Amplify.configure({ ...config, ssr: true })
export default async (req, res) => {
const { Auth } = withSSRContext({ req })
try {
const user = await Auth.currentAuthenticatedUser()
res.json({ user: user.username })
} catch (err) {
res.statusCode = 200
res.json({ user: null })
}
}
Ao navegar ou tentar acessar /api/check-user, você perceberá que o objeto de usuário está disponível quando você está autenticado e indisponível quando você não está autenticado.
Redirecionamento do lado do cliente
Freqüentemente, você irá detectar se um usuário está conectado e permitir o acesso ou redirecioná-lo com base na sessão ou suas credenciais.
Para fazer isso, você pode usar o gancho withRouther do Next.js, para navegar programaticamente com o usuário com base no estado de sua sessão.
Crie um novo arquivo no diretório pages chamado protected-client-route.js.
Aqui, adicione o seguinte código:
import { useState, useEffect } from 'react'
import { Auth } from 'aws-amplify'
import { useRouter } from 'next/router'
function ProtectedClient() {
const [user, setUser] = useState(null)
const router = useRouter()
useEffect(() => {
Auth.currentAuthenticatedUser()
.then(user => setUser(user))
// Se o usuário não estiver autenticado, redirecione ele para a página `/profile`
.catch(() => router.push('/profile'))
}, [])
if (!user) return null
return <h1>Hello {user.username} from client route!</h1>
}
export default ProtectedClient
Em seguida, adicione um link para esta rota em pages/_app.js :
<Link href="/protected-client-route">
<span className={linkStyle}>Protected client route</span>
</Link>
Se você tentar acessar a rota do cliente protegida, será redirecionado automaticamente para a rota do /profile se não estiver autenticado e se estiver autenticado, terá permissão para ver a página!
Redirecionamentos do lado do servidor
Um dos benefícios do SSR é a capacidade de implementar redirecionamentos do lado do servidor. Usar um redirecionamento do lado do servidor é mais seguro, pois você tem a opção de não renderizar nenhum html.
Abra pages/protected.js e atualize com o seguinte código:
// pages/protected.js
import { withSSRContext } from 'aws-amplify'
function Protected({ username }) {
return <h1>Hello {username} from SSR route!</h1>
}
export async function getServerSideProps({ req, res }) {
const { Auth } = withSSRContext({ req })
try {
const user = await Auth.currentAuthenticatedUser()
return {
props: {
authenticated: true,
username: user.username
}
}
} catch (err) {
res.writeHead(302, { Location: '/profile' })
res.end()
}
return {props: {}}
}
export default Protected
Ao tentar acessar esta rota, você será redirecionado para a rota do /profile se não estiver autenticado.
Login social (OAuth)
Para adicionar login social, execute amplify update auth e escolha Apply default configuration with Social Provider.
A partir daqui, você pode adicionar login social com Google, Facebook ou Amazon.
Depois que o login social for ativado, você poderá conectar os usuários do seu aplicativo usando o seguinte código:
// nome de usuário e password + todos os provedores de OAuth
Auth.federatedSignIn()
// specifying an OAuth provider
<button onClick={() => Auth.federatedSignIn({provider: 'Facebook'})}>Open Facebook</button>
<button onClick={() => Auth.federatedSignIn({provider: 'Google'})}>Open Google</button>
<button onClick={() => Auth.federatedSignIn({provider: 'Amazon'})}>Open Amazon</button>
Implantar o aplicativo Next.js na AWS com o Serverless Framework
Para implantar o aplicativo na AWS usando o Serverless Framework e o Serverless Next Component , primeiro crie um arquivo chamado serverless.yml na raiz do seu aplicativo.
Em seguida, adicione as duas linhas de configuração a seguir (sinta-se à vontade para alterar myNextApp para qualquer nome que você gostaria de usar):
myNextApp:
component: "@sls-next/serverless-component@1.16.0"
Em seguida, implante usando npx:
npx serverless
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment