」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 使用 Golang 進行身份驗證、授權、MFA 等

使用 Golang 進行身份驗證、授權、MFA 等

發佈於2024-11-07
瀏覽:876

"Ó o cara falando de autenticação em pleno 2024!"

Sim! Vamos explorar como realizar fluxos de autenticação e autorização, e de quebra, entender a diferença entre estar autenticado e estar autorizado (spoiler: não é a mesma coisa!).

Autenticação, Autorização, MFA e muito mais com Golang

Neste texto, falaremos sobre três tópicos importantes:

  • JWT (o queridinho do mundo stateless)
  • OAuth (aquele que vive nas sombras das APIs de terceiros)
  • Casdoor (uma ferramenta que promete facilitar sua vida)

Autenticação vs. Autorização: Entendendo a Treta

Se você já trabalhou com autenticação, provavelmente ouviu algo como: “Fulano foi autenticado, então ele pode acessar tal recurso”. Calma lá! Estar autenticado é apenas dizer: “Sim, você é você mesmo!”. Agora, autorização é outra parada — significa: “Você, mesmo sendo você, tem permissão para mexer aqui?”. Percebe a diferença?


JWT: JSON Web Tokens no Role

JWT é aquele formato que a gente ama... até começar a lidar com expiração, rotação de tokens e as temidas brechas de segurança. O básico é simples:

token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
    "user": "fulano",
    "admin": true,
    "exp":  time.Now().Add(time.Hour * 24).Unix(),
})
tokenString, err := token.SignedString([]byte("s3cr3t"))
if err != nil {
    log.Fatal(err)
}
fmt.Println("Token:", tokenString)

Simples, né? Um JWT é basicamente um pacote de informações assinado. O problema é que, depois de gerado, ele vive por aí, distribuído na rede. Por isso, controle bem o tempo de expiração e o armazenamento dos tokens!


OAuth

Quando você quer integrar com outros serviços, tipo permitir que o usuário faça login com Google, GitHub, ou aquele app de delivery, você provavelmente usará OAuth. A ideia é a seguinte: o serviço terceiro confirma quem é o usuário e devolve um token para você, dizendo: “Ele é quem diz ser e está autorizado a fazer tal coisa”.

A sequência geralmente é assim:

  1. O usuário clica em "Login com Google".
  2. Redirecionamos ele para o Google para se autenticar.
  3. Ele autoriza seu app a usar as informações.
  4. Seu app recebe um access token e, se for bonzinho, também um refresh token.

Casdoor

Agora, se você quer uma solução completa para autenticação e autorização que já vem com UI e suporte a múltiplos protocolos (JWT, OAuth, etc.), Casdoor pode ser uma boa opção. Ele é uma plataforma open-source, escrita em GOLANG para autenticação e autorização, projetada para facilitar a gestão de usuários e permissões em aplicações modernas. Ele oferece suporte a múltiplos protocolos de autenticação, como JWT, OAuth, SAML, LDAP, e até integração com serviços de identidade populares, como Google, GitHub, WeChat, entre outros.

Com o Casdoor, você obtém:

  • Interface de gerenciamento de usuários pronta para uso.
  • Administração centralizada de permissões e roles.
  • Integração fácil com APIs e front-ends em diferentes linguagens, incluindo Golang.
  • Multi-fator de autenticação (MFA) disponível para aumentar a segurança.
  • Suporte a OAuth e SSO (Single Sign-On), ideal para aplicações que precisam conectar múltiplos serviços.

Além de ser fácil de configurar, o Casdoor é ideal para quem quer rapidez na implementação e precisa de uma interface intuitiva para gerenciar usuários e autorização sem muito esforço.

Você pode explorar mais sobre o projeto no GitHub do Casdoor ou no site oficial.


Como Rodar o Casdoor com Docker para Testes

Se você quer experimentar o Casdoor rapidamente, a maneira mais fácil é rodá-lo com Docker usando a imagem casbin/casdoor-all-in-one. Esse contêiner já vem com tudo configurado (servidor e banco de dados), facilitando o processo.

Passo 1: Rodar o Casdoor com Docker

Execute o seguinte comando no terminal:

docker run -p 8000:8000 casbin/casdoor-all-in-one

Isso irá:

  1. Baixar a imagem do Casdoor (caso você ainda não tenha).
  2. Rodar o servidor Casdoor na porta 8000.

Passo 2: Acessar a Interface do Casdoor

Assim que o contêiner estiver rodando, você pode acessar a interface de administração no navegador:

http://localhost:8000

Passo 3: Login na Interface de Admin

As credenciais padrão para o login são:

  • Usuário: admin
  • Senha: 123

Com isso, você poderá explorar as funcionalidades do Casdoor, configurar provedores de autenticação, criar usuários e definir permissões.


Configuração Básica do Casdoor

1. Criar uma Organização

As organizações em Casdoor são usadas para agrupar usuários e aplicações. Siga as etapas para criar sua primeira organização.

Autenticação, Autorização, MFA e muito mais com Golang


2. Criar Provedores

Provedores permitem que você configure como os usuários podem se autenticar (Google, GitHub, LDAP, etc.). Adicione um ou mais provedores de autenticação.

Autenticação, Autorização, MFA e muito mais com Golang


3. Criar Adapters

Os adapters permitem que você integre o Casdoor a sistemas de autorização externos. Crie um adapter para conectar seu sistema de permissões.

Autenticação, Autorização, MFA e muito mais com Golang


4. Criar uma Aplicação

As aplicações permitem vincular usuários e provedores a um contexto específico. Crie uma aplicação e associe a uma organização e provedores.

Autenticação, Autorização, MFA e muito mais com Golang


Passo 5: Adicionar os Providers na Aplicação

Após criar sua aplicação, você precisa associar os provedores (Providers) a ela. Isso garante que a aplicação saiba quais métodos de login estarão disponíveis para os usuários.

  1. Acesse a aplicação que você criou.
  2. Adicione os provedores configurados previamente à lista de Providers da aplicação.

Autenticação, Autorização, MFA e muito mais com Golang


Passo 6: Configurar o Layout do Login e do Cadastro

O Casdoor permite personalizar as telas de login e cadastro para que fiquem com a cara da sua aplicação.

  1. Na interface de administração, acesse as configurações de UI da aplicação.
  2. Personalize as cores, logos e textos para o login e o cadastro.
  3. Visualize as mudanças em tempo real e salve.

Autenticação, Autorização, MFA e muito mais com Golang


Passo 7: Obter a URL para Autenticação

Após configurar tudo, você precisará da URL de autenticação para iniciar o fluxo de login a partir da sua aplicação.

  1. Acesse a aplicação e copie a URL de autenticação disponível na aba de configurações.
  2. Utilize essa URL para redirecionar usuários ao Casdoor quando precisarem se autenticar.

Exemplo de URL:

http://localhost:8000/login/oauth/authorize?client_id=[CLIENT_ID]&response_type=code&redirect_uri=http://localhost:9000/callback&scope=read&state=casdoor

Autenticação, Autorização, MFA e muito mais com Golang


Passo 8: Callback com o Code

Após o login bem-sucedido, o Casdoor redirecionará o usuário para a URL de callback com um code.

Exemplo de callback:

http://localhost:9000/callback?code=b1bf883de5a552aa43d6&state=casdoor

Esse code é temporário e será trocado por tokens para acessar recursos protegidos.


Passo 9: Obter Access Token, ID Token e Refresh Token

Após receber o code, você deve trocá-lo por tokens chamando a URL de token do Casdoor.

URL para Obter Tokens:

POST http://localhost:8000/api/login/oauth/access_token

Parâmetros necessários:

  • client_id: ID da aplicação.
  • client_secret: Segredo da aplicação.
  • code: O código recebido na URL de callback.
  • redirect_uri: A mesma URL usada no processo de login.
  • grant_type: "authorization_code".

A resposta incluirá:

{
  "access_token": "eyJhbGciOiJIUzI1...",
  "id_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "e5d92f3a...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Autenticação, Autorização, MFA e muito mais com Golang


Passo 10: Renovar o Access Token com o Refresh Token

Quando o access token expirar, você poderá obter um novo token usando o refresh token. Isso evita que o usuário precise fazer login novamente.

URL para Renovar o Token:

POST http://localhost:8000/api/login/oauth/refresh_token

Parâmetros necessários:

  • grant_type: "refresh_code".
  • client_secret: Segredo da aplicação.
  • client_secret: ID da aplicação.
  • refresh_token: O código JWT de refresh na URL de access_token.
  • scope: "read".

A resposta incluirá um novo json com tokens:

{
  "access_token": "eyJhbGciOiJIUzI1...",
  "id_token": "eyJhbGciOiJIUzI1NiIs...",
  "refresh_token": "e5d92f3a...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Autenticação, Autorização, MFA e muito mais com Golang


API Completa e SDKs para Integração

O Casdoor também disponibiliza uma API completa documentada no Swagger, permitindo que você crie telas de autenticação totalmente customizadas e adapte o fluxo de login às necessidades do seu projeto. Além disso, ele oferece SDKs para diversas tecnologias populares, como Flutter, React, Vue, Angular, e muito mais, facilitando a integração com diferentes stacks e plataformas. Com essas ferramentas, você tem flexibilidade para implementar autenticação de maneira rápida e eficiente, seja para aplicações web ou mobile.

GET http://localhost:8000/swagger/

Autenticação, Autorização, MFA e muito mais com Golang


Integração com Casbin para Autorização

Além da autenticação, o Casdoor pode ser integrado com o Casbin, uma poderosa biblioteca de autorização baseada em políticas. O Casbin permite definir quem pode acessar quais APIs e recursos de forma flexível, utilizando uma abordagem baseada em regras. Com suporte a diversos modelos, como ACL (Access Control List), RBAC (Role-Based Access Control) e ABAC (Attribute-Based Access Control), o Casbin facilita o controle granular de permissões.

A combinação de Casdoor para autenticação e Casbin para autorização oferece uma solução robusta para controlar o acesso em suas aplicações. Você pode, por exemplo, autenticar o usuário com Casdoor e utilizar o Casbin para verificar se ele tem permissão para acessar uma rota ou recurso específico.


Como Funciona o Enforce no Casbin

O método Enforce é o coração do Casbin. Ele é responsável por verificar se uma determinada solicitação de acesso deve ser permitida ou negada com base nas políticas definidas. O método recebe três parâmetros principais: sub (o sujeito, ou usuário), obj (o objeto, ou recurso) e act (a ação, como GET ou POST). Se a política permitir a combinação desses três elementos, o Casbin retorna true, indicando que o acesso é autorizado; caso contrário, retorna false.

Por exemplo, no código abaixo, o Casbin verificará se o usuário pode realizar uma ação específica no recurso solicitado:

ok, err := e.Enforce("alice", "/admin", "GET")
if err != nil {
    log.Fatal(err)
}
if ok {
    fmt.Println("Acesso permitido")
} else {
    fmt.Println("Acesso negado")
}

Esse processo garante que o acesso seja controlado dinamicamente com base nas permissões definidas na política, evitando que ações não autorizadas sejam executadas.


Exemplos de Uso em Controllers HTTP e Recursos

Aqui está um exemplo de como usar Casbin em uma aplicação Go para autorizar acesso a uma rota HTTP:

Exemplo de Middleware para Autorização com Casbin

package main

import (
    "github.com/casbin/casbin/v2"
    "net/http"
)

func authorize(e *casbin.Enforcer, sub, obj, act string) bool {
    ok, err := e.Enforce(sub, obj, act)
    if err != nil {
        return false
    }
    return ok
}

func middlewareAuth(e *casbin.Enforcer, next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        user := r.Header.Get("user") // Obtém o usuário do cabeçalho
        resource := r.URL.Path       // Recurso sendo acessado
        action := r.Method           // Método HTTP (GET, POST, etc.)

        if !authorize(e, user, resource, action) {
            http.Error(w, "Forbidden", http.StatusForbidden)
            return
        }

        next.ServeHTTP(w, r) // Continua se autorizado
    })
}

Exemplo de Política RBAC (Role-Based Access Control)

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

[policy]
p, admin, /admin, GET
p, user, /profile, GET

[role_assignment]
g, alice, admin
g, bob, user

Nesta política, o admin tem acesso à rota /admin e o user à rota /profile. O usuário Alice é atribuído ao papel de admin, enquanto Bob é um user.


Com essa abordagem, você pode criar sistemas seguros e escaláveis, combinando autenticação com o Casdoor e autorização com o Casbin. Explore os links para mais exemplos e ajuste a implementação conforme as necessidades do seu projeto.

Configuração no Casdoor

Passo 1: Criar o modelo

Autenticação, Autorização, MFA e muito mais com Golang


Passo 2: Definir o Enforce

Autenticação, Autorização, MFA e muito mais com Golang


E por fim, o MFA.

Como Configurar MFA no Casdoor

A Autenticação Multi-Fator (MFA) adiciona uma camada extra de segurança ao processo de login. Com ela, mesmo que alguém descubra a senha do usuário, será necessário um segundo fator para concluir a autenticação, como um código gerado por um app autenticador (Google Authenticator, Authy, etc.).

Passo 1: Adicionar autenticação 2 fatores no usuário.

Possível pela interface web ou implementando na API do casdoor para o usuário específico.

Autenticação, Autorização, MFA e muito mais com Golang


Passo 2: Realizar o Login

Ao realizar o login deve pedir o código de autenticação para validação.

Autenticação, Autorização, MFA e muito mais com Golang

Simples, não?


Conclusão

Autenticação e autorização são como aquelas engrenagens que, juntas, mantêm o sistema rodando redondo. A autenticação confirma quem é o usuário, enquanto a autorização define o que ele pode fazer. Não basta saber quem está logado; é preciso garantir que cada um só tenha acesso ao que realmente pode. É tipo festa: uma coisa é passar pela entrada, outra é conseguir entrar na área VIP.

Com o Casdoor, fica fácil gerenciar o processo de autenticação. Ele oferece uma variedade de opções, como login com Google, GitHub, além de integração com protocolos como JWT e OAuth. Já o Casbin é o cara que define as regras e garante que cada recurso seja acessado por quem tem permissão, funcionando como uma política de segurança que você controla.

Usar essas duas ferramentas juntas é uma solução poderosa. O Casdoor garante que só usuários legítimos passem pela porta, enquanto o Casbin faz o controle fino, autorizando ou bloqueando ações com base em regras personalizadas. E o melhor é que tudo isso pode ser integrado facilmente via API, com direito a documentação no Swagger e SDKs para várias tecnologias, como Flutter, React e Vue.

Com essa combinação, seu sistema fica bem organizado e seguro, sem complicação. Agora é só botar a mão na massa e deixar tudo funcionando como deve. No fim das contas, um sistema bem protegido é como uma festa bem organizada: quanto mais controle, mais tranquilo é para todo mundo se divertir e aproveitar!

版本聲明 本文轉載於:https://dev.to/booscaaa/autenticacao-autorizacao-mfa-e-muito-mais-com-golang-1go5?1如有侵犯,請聯絡[email protected]刪除
最新教學 更多>
  • ES6 類別是 JavaScript 原型模式的語法糖嗎?
    ES6 類別是 JavaScript 原型模式的語法糖嗎?
    ES6 類別只是 Javascript 中原型模式的語法糖嗎? 不,ES6 類別不僅僅是 Javascript 原型模式的語法糖原型模式。 雖然它們確實有一些相似之處,但也存在一些關鍵差異,這些差異使 ES6 類別成為創建和使用物件的更強大、更方便的方式。 以下是關鍵差異的細分ES6 類別與原型模...
    程式設計 發佈於2024-11-07
  • #daysofMiva 挑戰賽的第一天。
    #daysofMiva 挑戰賽的第一天。
    100 天挑戰的第一天 日期: 8/21/2024 目標: 學習並理解 JavaScript 中的變數、邏輯運算和資料類型,使用 JavaScript 解決數學問題,並開始學習事件監聽器和條件語句。 1. JavaScript變數介紹 今天,我透過學習變數開始了 JavaScrip...
    程式設計 發佈於2024-11-07
  • 如何將 PHP 產生的值安全地整合到 JavaScript 程式碼中?
    如何將 PHP 產生的值安全地整合到 JavaScript 程式碼中?
    將PHP 產生的值合併到頁面上的JavaScript 中嘗試將PHP 產生的值嵌入到JavaScript 程式碼中時,您可能會遇到類似於給定範例中的錯誤。要解決此問題,請考慮以下方法:<?php $htmlString = 'testing'; ?> <html> &l...
    程式設計 發佈於2024-11-07
  • 了解非同步 JavaScript
    了解非同步 JavaScript
    JavaScript 是一種單執行緒語言,這意味著它一次只能做一件事。然而,Web 應用程式通常需要執行從伺服器取得資料等任務,這可能需要一些時間。如果 JavaScript 必須等待每個任務完成才能繼續,那麼您的 Web 應用程式將會變得緩慢且無回應。這就是非同步(async)JavaScript...
    程式設計 發佈於2024-11-07
  • 您應該避免的錯誤(以及如何修復它們)
    您應該避免的錯誤(以及如何修復它們)
    身為 React 開發人員,很容易陷入某些編碼模式,這些模式一開始看起來很方便,但最終可能會導致問題。在這篇文章中,我們將探討 5 個常見的 React 錯誤,並討論如何避免它們,確保您的程式碼保持高效、可維護和可擴展。 1. 濫用關鍵道具 錯誤: {myList.map((ite...
    程式設計 發佈於2024-11-07
  • 如何在 PHP 中存取 JavaScript 變數值?
    如何在 PHP 中存取 JavaScript 變數值?
    在PHP 中使用JavaScript 變數值使用同時涉及JavaScript 和PHP 的Web 應用程式時,通常需要在兩者之間交換資料兩種語言。然而,由於語言的執行環境不同,直接在 PHP 中存取 JavaScript 變數是不可能的。 PHP 在伺服器端執行,而 JavaScript 在客戶端運...
    程式設計 發佈於2024-11-07
  • Popver API VS 對話方塊模態:相同但不同
    Popver API VS 對話方塊模態:相同但不同
    我在閱讀一些科技新聞部落格時偶然發現標題 Popover API 登陸 Baseline。我很困惑,在我最近深入前端開發期間,我最近很難習慣在 HTML 中使用 Elements。在瀏覽部落格時,我一直對到目前為止我如何使用該元素感到困惑。 長話短說 選擇: 需要使用者焦點的模態彈...
    程式設計 發佈於2024-11-07
  • Go中不嵌入結構體可以實現方法繼承嗎?
    Go中不嵌入結構體可以實現方法繼承嗎?
    嵌入式結構:方法繼承的探索理解Go 中的方法繼承 In在Go 中,將方法從一種類型繼承到另一種類型的能力主要是透過嵌入結構來實現的。此技術涉及將一個結構嵌入另一個結構,允許外部結構存取和利用嵌入結構的方法。 嵌入結構的範例考慮以下內容程式碼片段:type Properties map[string]...
    程式設計 發佈於2024-11-07
  • 如何在 PHP 中的 Foreach 迴圈中檢索數組鍵
    如何在 PHP 中的 Foreach 迴圈中檢索數組鍵
    在Foreach 循環期間檢索數組鍵:PHP在PHP 中使用數組時,通常需要檢索其中的鍵和值foreach 循環。 key() 函數提供了一種在迭代期間存取當前鍵的便捷方法。但是,在某些情況下,它可能不會產生所需的結果。 考慮以下程式碼,其目的是從範例陣列產生 HTML 表:foreach($sam...
    程式設計 發佈於2024-11-07
  • 在 JavaScript 中建立物件的方法
    在 JavaScript 中建立物件的方法
    介紹 在 JavaScript 中建立物件的方法有很多種。 對象字面量 Object() 建構子 Object.create() 建構子 ES6 類 對象字面量 這可能是在 JavaScript 中建立物件最快、最簡單的方法。這也稱為物件初始值設定項,是一個由零對...
    程式設計 發佈於2024-11-07
  • 如何在 JavaScript 中擴充自訂異常的錯誤物件?
    如何在 JavaScript 中擴充自訂異常的錯誤物件?
    擴充JavaScript 中的錯誤物件在JavaScript 中拋出例外時,可能想要擴充內建Error 物件以建立自訂錯誤類型。這允許更具體和資訊豐富的異常處理。 在JavaScript 中,繼承不是透過子類化與Python 不同,在Python 中,異常通常是從Exception 基類進行子類化的...
    程式設計 發佈於2024-11-07
  • MySQL如何保證並發操作時資料的完整性?
    MySQL如何保證並發操作時資料的完整性?
    MySQL 並發:確保資料完整性如果您的MySQL 資料庫使用InnoDB 儲存引擎,您可能會擔心在執行過程中潛在的並發問題。同時記錄更新或插入。本文探討了 MySQL 如何處理並發以及是否需要在應用程式中加入額外的處理。 MySQL 的同時處理MySQL 採用原子性,這意味著單獨的 SQL 語句是...
    程式設計 發佈於2024-11-07
  • 如何使用 Go 在 SQL 查詢中有效連接字串和值?
    如何使用 Go 在 SQL 查詢中有效連接字串和值?
    在Go 中有效地製作SQL 查詢在Go 中將字串與文字SQL 查詢中的值連接起來可能有點棘手。與 Python 不同,Go 的字串格式化語法行為不同,導致常見錯誤,如此處遇到的錯誤。 元組語法錯誤初始程式碼片段嘗試使用 Python -style 元組,Go 中不支援。這會導致語法錯誤:query ...
    程式設計 發佈於2024-11-07
  • 為什麼 json_encode() 無法使用 Latin1 編碼對 MySQL 資料庫中的重音字元進行編碼?
    為什麼 json_encode() 無法使用 Latin1 編碼對 MySQL 資料庫中的重音字元進行編碼?
    MySQL 中UTF-8 字元的JSON 編碼難題當嘗試使用latin1_swedish_ci 編碼從資料庫中檢索重音字元並使用json_encode() 將它們編碼為JSON 時,結果可能出乎意料。預期結果(例如“Abord â Plouffe”)會轉換為“null”,從而使編碼的 JSON 無效...
    程式設計 發佈於2024-11-07
  • 如何在 MySQL 中將行轉置為列:綜合指南
    如何在 MySQL 中將行轉置為列:綜合指南
    在MySQL 中將行轉換為列在MySQL 中將行轉換為列在MySQL 查詢中將行轉換為列需要在應用程式中執行複雜的查詢或手動操作。 GROUP_CONCAT 解雖然 GROUP_CONCAT 可以將行轉換為單列,但它不提供整個結果集所需的轉置。 手動查詢方法對於更複雜的轉置,需要細緻的查詢,從原始行...
    程式設計 發佈於2024-11-07

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3