Authentication Go中的人员如何管理身份验证?

Authentication Go中的人员如何管理身份验证?,authentication,go,Authentication,Go,对于那些在Go中构建RESTful API和JS前端应用程序的人,您如何管理身份验证?您是否使用了任何特定的库或技术 我很惊讶地发现关于这个的讨论如此之少。我记住了如下答案,并试图避免开发自己的实现: 每个人都在分别编写自己的解决方案吗?您可以使用中间件进行身份验证 您可以尝试基本和摘要身份验证以及OAuth2 但如何认证实际上取决于你的应用程序 身份验证将状态/上下文引入到http.Handlers中,最近对此进行了一些讨论 对上下文问题的已知解决方案进行了分析和描述 我提出了一个更通用的解

对于那些在Go中构建RESTful API和JS前端应用程序的人,您如何管理身份验证?您是否使用了任何特定的库或技术

我很惊讶地发现关于这个的讨论如此之少。我记住了如下答案,并试图避免开发自己的实现:


每个人都在分别编写自己的解决方案吗?

您可以使用中间件进行身份验证

您可以尝试基本和摘要身份验证以及OAuth2

但如何认证实际上取决于你的应用程序

身份验证将状态/上下文引入到http.Handlers中,最近对此进行了一些讨论

对上下文问题的已知解决方案进行了分析和描述

我提出了一个更通用的解决方案,不需要全局状态,因为它可以与其他两个一起使用,也可以不使用其他两个,并且与上下文无关的中间件很好地集成


提供go http auth与go on/wrap的集成。

这个问题获得了大量的视图,并且有一个流行的问题标签——因此我知道人们对这个话题有很多潜在的兴趣,许多人问的都是同样的问题,在互联网上找不到答案

大多数可用的信息都会产生与手波浪一样的文本形式,作为“读者练习”。)

然而,我终于找到了一个具体的例子,(慷慨地)由golang nuts邮件列表的一名成员提供:

这提供了一个建议的模式和服务器端实现,作为自定义身份验证的基础。客户端代码仍然由您决定

(我希望这篇文章的作者看到这一点:谢谢!)

摘录(并重新格式化):


“我建议如下设计:

create table User (
 ID int primary key identity(1,1),
 Username text,
 FullName text,
 PasswordHash text,
 PasswordSalt text,
 IsDisabled bool
)

create table UserSession (
 SessionKey text primary key,
 UserID int not null, -- Could have a hard "references User"
 LoginTime <time type> not null,
 LastSeenTime <time type> not null
)
创建表用户(
ID int主键标识(1,1),
用户名文本,
全名文本,
密码哈希文本,
密码salt text,
IsDisabled bool
)
创建表用户会话(
SessionKey文本主键,
UserID int not null,--可能有一个硬“引用用户”
登录时间不为空,
LastSeenTime不为空
)
  • 当用户通过TLS下的POST登录到您的站点时,请确定密码是否有效
  • 然后发出一个随机会话密钥,比如说50个或更多的加密随机字符,然后放入一个安全Cookie中
  • 将该会话密钥添加到UserSession表中
  • 然后,当您再次看到该用户时,首先点击UserSession表,查看SessionKey是否包含有效的LoginTime和LastSeenTime,并且用户未被删除。您可以将其设计为计时器自动清除UserSession中的旧行。”

另一个用于处理cookie身份验证的开源软件包是


(顺便说一句,是我写的)

另一个可能的解决方案是最近在邮件中宣布的

(我还没有尝试使用此库。)


另请参见2018年回答这一问题。我建议使用JWT(JSONWeb令牌)。您标记的答案有一个缺点,即它在前面(用户)和后面(服务器/db)执行的行程。更糟糕的是,若用户频繁请求需要身份验证,则会导致从/到服务器和数据库的请求膨胀。为了解决这个问题,使用JWT将令牌存储在用户端,用户可以在任何需要访问/请求的时候使用该令牌。无需访问数据库和服务器处理来检查令牌的有效性,这需要很短的时间

看看-它将RESTful API和前端应用程序的身份验证包装到中间件中,您可以使用中间件来保护特定的API路由

例如,设置基本身份验证与为
/admin
路由创建新的子计算机一样简单:

e.Group("/admin").Use(middleware.BasicAuth(func(username, password string, c echo.Context) (bool, error) {
    if username == "joe" && password == "secret" {
        return true, nil
    }
    return false, nil
}))

老实说,有很多身份验证方法和技术可以安装到应用程序中,这取决于应用程序的业务逻辑和需求。
例如Oauth2、LDAP、本地身份验证等
我的回答假设您正在寻找本地身份验证,这意味着您在应用程序中管理用户的身份。 服务器必须公开一组允许用户和管理员使用的外部API 管理帐户以及他们希望如何向服务器标识自己,以实现可靠的通信。 您将创建一个包含用户信息的DB表。 其中,出于安全目的对密码进行哈希处理,请参阅

假设应用程序要求基于以下方法之一对用户进行身份验证:

  • 基本身份验证(用户名、密码):
    此身份验证方法取决于在base64中编码并在中定义的授权标头中设置的用户凭据,基本上是在应用程序接收到用户请求时,解码授权并重新散列密码,以便在DB散列中对其进行比较(如果与用户身份验证匹配),否则将401状态代码返回给用户

  • 基于证书的身份验证:
    此身份验证方法依赖于数字证书来识别用户, 它被称为x509 auth,因此当应用程序收到用户请求时,它会读取客户端的证书,并验证它是否与提供给应用程序的CA根证书匹配

  • 承载令牌:
    这种身份验证方法依赖于短期访问令牌,承载令牌是一个神秘的字符串,通常由服务器响应登录请求生成。因此,当应用程序收到用户请求时,它会读取授权并验证令牌以对用户进行身份验证

不过,我还是推荐你 对于身份验证库,它通过一组可扩展的身份验证方法(称为策略)进行身份验证。Go Guardian基本上不装载路由或采用任何特定的数据库模式,这最大限度地提高了灵活性,并允许开发人员做出决策

设置go guardian身份验证程序非常简单

下面是上述方法的完整示例<