Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: autenticação via Github #89

Merged
merged 30 commits into from
Apr 10, 2023
Merged

feat: autenticação via Github #89

merged 30 commits into from
Apr 10, 2023

Conversation

vinifraga
Copy link
Contributor

📋 Descrição

Bom dia pessoal, trago uma proposta de autenticação com o Clerk principalmente para o mobile, mas também sugestões para o backend. Vou dividir essa issue em duas seções: mobile e back.

Mobile

Libs utilizadas:

Docs utilizadas:

Proposta

Utilizarmos o contexto AuthContext para gerenciar todo o fluxo que precisarmos de autenticação, deixando "transparente" para o restante dos devs as particularidades do Clerk. Esse contexto disponibiliza as seguintes funções e variáveis:

  • user: dados do usuário que devemos utilizar ao longo da aplicação como id, email, nome completo e foto de perfil;
  • signInOrSignUpWithOAuth: função que autentica o usuário de acordo com o provider escolhido. Por enquanto, utilizamos apenas o GitHub. Além disso, ela também automaticamente gerencia se o usuário precisa ser cadastrado (primeiro acesso) ou logado;
  • signOut: função para deslogar o usuário;
  • getSessionInfo: função que retorna as informações da sessão do usuário necessárias para a validação das requisições no backend;
  • isLoading: variável que retorna true caso alguma das três funções anteriores estiverem sendo executadas.

Para consumir os dados desse contexto, criei um hook chamado useAuth (temos que tomar cuidado na importação pois o @clerk/clerk-expo exporta um hook de mesmo nome)

Para centralizar os providers em um ambiente, sugiro a estrutura do AppProvider

Apesar do Clerk não disponibilizar componentes visuais no Expo, sugiro utilizarmos os helpers SignedIn e SignedOut para exibir condicionalmente componentes dependendo do status da autenticação do usuário.

Problemas

Apesar da documentação do Clerk acusar que a SDK deles não é compatível com a SDK 48 do Expo, não encontrei nenhum problema com a lib deles. Porém, definitivamente o maior empecilho dessa PR foi a incompatibilidade da SDK 48 do Expo e a lib expo-auth-session no Expo Go iOS. Tentei de várias formas resolver esse problema mas não consegui. Então quem for tentar autenticar no Expo Go via iOS não funciona por enquanto. Existe uma gambiara caso você realmente precise autenticar via iOS:

const authResult = await AuthSession.startAsync({
  authUrl: externalVerificationRedirectURL.toString(),
  projectNameForProxy: `@NOME_DA_SUA_CONTA_EXPO/${Constants.manifest.scheme}`
})

Backend

Libs utilizadas:

Docs utilizadas:

Proposta

Aqui não me aprofundei muito pessoal, basicamente importei os métodos sessions e users da SDK para validar a sessão e buscar os dados do usuário, respectivamente. Então basicamente editei a rota no AppController.tsx para receber os parâmetros sessionId e token que o mobile envia, validei a sessão, obtive o id do usuário e o utilizei para buscar o restante das informações.

Problemas

Como a SDK do Clerk já retorna uma instância inicializada e populada automaticamente com a variável ambiente CLERK_SECRET_KEY, eu tive que realizar o import 'dotenv/config'. Além disso, como não temos uma recipe do NestJS para o Clerk e como o Clerk retorna uma função em vez de uma classe, tive dificuldade em criar um provider como fizemos com o Prisma.

Fixes #61

🛠️ Tipo da mudança

Exclua as opções que não são relevantes.

  • Nova feature

🧪 Como isso foi testado?

Não adicionei testes para essa parte pois ainda precisamos definir o setup de testes no mobile.

✅ Checklist:

  • O título do meu PR está seguindo o padrão <type>(scope): subject. Por exemplo: feat(mobile): add new feature
  • Meu código segue as diretrizes de estilo deste projeto
  • Realizei uma auto revisão do meu código
  • Fiz alterações correspondentes na documentação
  • Minhas alterações não geram novos alertas
  • Adicionei testes para minhas alterações

@vinifraga vinifraga mentioned this pull request Apr 7, 2023
5 tasks
@vinifraga vinifraga changed the title Autenticação via Github feat: autenticação via Github Apr 7, 2023
async getUsers() {
const users = await this.prisma.user.findMany()
@Post()
async getUser(@Req() request: Request, @Res() response: Response) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

acho que tá um pouquinho estranho esse @Post() e o nome da função começa com get

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa, eu só editei o método que tinha pra testar a requisição do mobile e acabei deixando o nome antigo 😅

@diego3g
Copy link
Owner

diego3g commented Apr 8, 2023

@vinifraga brabo demais! resolve os conflitos pra nós?

@@ -1,3 +1,4 @@
import 'dotenv/config'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No Nest acredito que não precisa disso se usarmos o ConfigModule

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Se não realizar esse import, o clerk não entende a váriavel ambiente CLERK_SECRET_KEY.

async function handleVerifySession() {
try {
const { sessionId, token } = await getSessionInfo()
const response = await axios.post('http://192.168.15.4:3333', {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho legal colocar a url via env, não?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Esse código no mobile é apenas para demonstração e teste da funcionalidade aqui na PR, essa página não existe no figma. Vou apagar esse código ao final, mas posso deixar um service com uma env para o IP.

token,
})

console.log(response.data)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui sobrou um console log

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Esse código no mobile é apenas para demonstração e teste da funcionalidade aqui na PR, essa página não existe no figma.

Comment on lines +13 to +23
const sessionId = request.body.sessionId
const token = request.body.token

if (typeof sessionId === 'string') {
const session = await sessions.verifySession(sessionId, token)

if (!session) {
return response.status(400).json({
error: 'Session not verified',
})
}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Acho que todo esse bloco de código poderia ser substituído pelo auth guard criado por @eletroswing na PR #94

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Boa, esse código no back é apenas para demonstração e teste da funcionalidade aqui na PR, toda melhora é bem vinda mas como não trabalho muito com NestJS vou deixar essa parte para outra pessoa.

@vinifraga
Copy link
Contributor Author

@vinifraga brabo demais! resolve os conflitos pra nós?

Opa, por aqui na PR disse que não tenho acesso. Tem alguma sugestão?

image

@diego3g
Copy link
Owner

diego3g commented Apr 9, 2023

@vinifraga você precisa resolver os conflitos localmente, isto é, combinar o código mais atualizado do projeto com o código que você fez. Isso pode ser feito utilizando rebase ou dando um "git pull origin main" na sua branch e passando por cada conflito e resolvendo. Se quiser ajuda, me chama Discord.

@vinifraga
Copy link
Contributor Author

Bom dia pessoal, encontrei esse artigo trazendo atualizações do Clerk para o Expo:

https://clerk.com/blog/changelog-2023-04-07?utm_source=changelog&utm_medium=email_campaign

Vou testar esse novo hook para ver se funciona bem e resolve o problema do Login social no iOS.

@diego3g
Copy link
Owner

diego3g commented Apr 10, 2023

@vinifraga Vou aguardar você testar isso antes de dar merge.

@diego3g diego3g added the enhancement New feature or request label Apr 10, 2023
@vinifraga
Copy link
Contributor Author

Essas últimas alterações foram implementar algumas mudanças pontuais:

  • Atualizar o @clerk/clerk-expo para a versão 15 que traz um novo hook totalmente voltado para autenticação social OAuth, resolvendo aquele problema do iOS que levantei anteriormente e deixando bem mais simples a autenticação.
  • Ajustar o Expo Router para redirecionamento da autenticação no Android (ele redireciona para a rota oauth-native-callback. Criei essa rota e redireciono dela para o irmão mais próximo automaticamente.
  • E outras melhorias gerais ao integrar com alterações da main como unificar tudo no AppProvider, remove exemplo de env incorreto, adicionar mais pastas no paths do Typescript, etc.

@vinifraga vinifraga requested a review from diego3g April 10, 2023 22:33
@diego3g diego3g merged commit b3a8fc6 into diego3g:main Apr 10, 2023
@diego3g diego3g mentioned this pull request Apr 11, 2023
21 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[0008] Autenticação via Github
5 participants