HTTP验证大法(Basic Auth,Session, JWT, Oauth, Openid)

时间:2017-02-27 00:56:49   收藏:0   阅读:2559

本文标签:   HTTP Auth OpenID HTTP验证大法 Session REST   服务器

成为一个"认证”老司机

本文翻译自 Auth-Boss 。 如果有翻译的不恰当或不对的地方, 欢迎指出。

成为一个认证老司机, 了解网络上不同的身份认证方法。

本文档的目的是记录和编目Web上的身份验证方法。

认证指的是创建一个系统的过程,用户可以通过该系统“登录”在线服务,并授予对受保护资源的访问权限。

以下引用可能更好地总结我想要解释的内容:

客户端认证涉及向Web上的服务器证明客户端(或用户)的身份。[1]

Who

我是一个自学成才的开发人员,热爱开源技术,学习,指导和知识共享。

Why

我写这篇指南,因为关于验证这方面的信息很难直接找到。我决定戴上我的“研究帽“,做一些跑腿的工作。

How

我写作风格简洁,会用到一些技术词。

免责声明:本文档不作为包含所有认证方法的网络的目录;

本文档也不旨在提供“最佳”认证方法。

没人给钱贿赂我。

如果你想赞助我那更棒, 可以用一些其它方式, 比如领养一只小狗,或者帮助正在辛劳的人们。

引文:这些引文表示我引用的来源。

如果你想让我收下链接/更好地引用我的来源(不仅仅是一个链接到原始发布),我可以这样做。

如果你想让我更好的引用引文, 我当然愿意,不过请先让我知道<3。

遗漏,错误:

犯错并不罕见,我并不是安全方面的专家

如果你看到一些可以改进的东西请PR,告诉我哪里弄错了,我可以改进。

有关PR更多的信息,请查看CONTRIBUTIONS.md。

假想案例

我将使用本文档中的一个常见示例来说明在“客户端”(用户在其计算机前面)和“服务器”(后台)上发生的情况的登录流程。

我们的例子将会有一个想象的朋友:Beorn。

Beorn喜欢针织,经常去 http://knittingworld.com 购买用品。

Beorn在knittingworld有一个帐号,我们将看到他登陆的例子。

一般最佳做法

在讨论用于管理身份验证的技术之前,以下是你不应该做的。

以下某些项目可能不直接与登录/身份验证/用户注册有关,但通常有用。

一些忠告

我们还发现许多网站设计自己的身份验证机制,以提供更好的用户体验。

不幸的是,设计师和实现者通常没有安全背景,因此不能很好地理解他们可以使用的工具[2]

术语

web验证开发领域中有相当多的术语。

下面是一个术语列表,您将在下面看到。

HTTP 超文本传输协议。

这是一个大的概念。我只能简单的解释一下它的含义。

Web是围绕HTTP构建的 - 它是用于在Web服务器和用户之间通信的协议。

您的浏览器被视为HTTP客户端,因为它向HTTP服务器发送请求。

你的客户可以做很多不同类型的请求, - 你可能听说过一些最流行的请求 - POST POST PUT和DELETE。

HTTP服务器向您的浏览器 - 客户端发送响应。

这些响应就是资源。

资源可以是(但不限于):HTML文件,图像,文本,JSON等。

你可以认为资源是从服务器返回的“文件”。

关于此主题的其他链接:

HTTPS

HTTPS是安全的HTTP。

它与SSL / TLS密切相关。

最初在互联网上的支付交易很受欢迎,最近变得越来越普遍。

您可能会认为https是“在浏览器中显示在我的网址左侧的绿色文本”;

经常伴随着锁的图标或类似的东西。

HTTPS是用TLS(或在过去的日子里,SSL)封装的HTTP,以保护浏览器和服务器之间的流量。

HTTPS会对与您的HTTP请求一起发送的信息和发回的响应进行加密。

这在我们开始谈论身份验证时尤其重要!

来自维基百科:

HTTPS在不安全的网络创建安全通道。

这确保了合理的保护免受窃听者和中间人攻击,只要使用足够的密码套件并且服务器证书被验证和信任。

TLS / SSL

TLS和SSL是加密协议。

TLS和SSL加密您通过网络发送的数据 - 它旨在防止人们“窃听”或篡改您要发送的数据。

SSLv2和v3今天被视为不安全(请参阅 POODLE ),因此大多数HTTPS是使用TLS 1.2完成的。

YouTube上有一些有用的视频,有助于解释这些复杂的问题,

这个视频 MIT opencourseware 挺不错的!

State

statestatefulstatelesspiece of state

这些是术语,它们的定义不同。

在本文里,“piece of state”或“stateful”描述了一块存储在内存中的数据。

HTTP请求通常被描述为“stateless”。

当您访问网站和登录时,您正在传递一些信息以及您的HTTP请求, 用来标识您的身份。

无论你需要使用什么身份验证方法来识别自己,都必须“附加”到某个或另一个HTTP请求,因为你不能简单地将该状态放在HTTP协议本身中 - 必须采取另一种形式,可以凌驾于HTTP协议之上(正如你会看到在本文档的其余部分。)。

可能有点夸张... 我认为这篇来自苏格兰的文章解释的很不错 The Ins and Outs of Token Based Authentication

由于HTTP协议是无状态的,这意味着如果我们使用用户名和密码验证用户,那么在下一个请求,我们的应用程序将不知道我们是谁。

我们必须再次验证。

Cookies

Cookie是存储在用户浏览器上的小数据。

Cookie与HTTP相反,是有状态的 - 这意味着尽管HTTP不能存储用户信息,但是cookie可以。

网络Cookie的常见示例:

Beorn访问 http://knittingworld.com 为他的下一个针织项目购买一些不错的纱线和材料。

他登录后向他的购物车添加了三件商品。突然他听到一声砰!

并意识到他的微波炉里还有一罐金枪鱼。不好!

Beorn关闭了浏览器,立即忘记了他购物车里的东西,跑去检查微波炉。

罐头金枪鱼的酱汁已经洒在他家的地板上,Beorn回到他的电脑前,并重新访问 https://knittingworld.com ...想看看他之前加入购物车的商品还在不在。

Cookies。

有不同种类的Cookies。

有些Cookie会在您的浏览器中停留多天,而其他Cookie会在您关闭浏览器后立即消失。

Cookie在过去(仍然是)认证中起到了很大的作用。

Web服务器通常使用认证cookie来确定用户是否登录以及他们有权访问哪些资源。

持久性cookie 有时会带来麻烦,因为它们可以被广告商用来记录关于用户的web习惯的信息。

另一方面,它们通常用于保存用户每次访问站点时不必重新输入其登录凭证。

您可以通过导航到您的(使用Chrome)开发者工具并打开网络标签查看与请求一起发送的Cookie。

刷新页面将显示传入资源的列表,您可以选择其中的一个。

滚动列表, 看看找得到cookie不!

您也可以在开发人员工具的[Application]标签中查看Cookie 的相关信息。

Sessions / Session Management

我并不会一开始就去尝试简单的描绘出sessions,我会引用OWASP:

网络会话是与同一用户相关联的网络HTTP请求和响应事务的序列。

现代和复杂的web应用程序需要在多个请求期间保留关于每个用户的信息或状态。

因此,会话提供了建立变量的能力,例如访问权限和本地化设置,这将适用于在会话期间用户与webApp的每一次交互。

您可以在下面的“Methodologies”部分找到基于会话身份验证的示例。

关于Sessions的更多链接:

Methodologies

以下是用于建立认证的技术方案列表。这不是一个完整的列表!

HTTP基本认证

HTTP基本身份验证(或“基本身份验证”)已经存在了很长时间。看起来人们倾向于使用它,因为它的简单性,它支持跨浏览器。这是一个空白页面,要求基本的验证。这里将演示如何确保webApp正常运行当Beorn关闭游览器重新再打开后:

关于HTTP基本身份验证的一些重要注意事项:

链接

基于Session的认证

Session认证已经存在了一段时间,并且平常用的比较多。基于session的身份验证的关键是,用户的登录与服务器上的内存的一段状态或key-value存储(如Redis中)相关联。

让我们看看我们的朋友Beorn使用基于session的身份验证的示例。

基于Token的认证

基于令牌的认证已经变得更加普遍最近随着RESTful API的应用,单页应用程序和微服务的兴起。

什么是token?

token是一小块数据。

利用基于Token的认证的认证系统意味着用户向服务器发出的请求携带token以执行认证逻辑。当发出HTTP请求时, token是验证用户是否有资格访问资源的凭证。

这与基于Cookie的身份验证有何不同?

token认证是无状态的,而基于session的认证意味着在您的服务器(或在Redis等)中的某个地方保存着状态用以识别用户。

Auth0的博客文章 Cookies vs Tokens:The Definitive 描述了cookie和令牌之间的身份验证流程的差别的:

基于session的认证流程:

1. 用户输入其登录信息
2. 服务器验证信息是否正确,并创建一个session,然后将其存储在数据库中
3. 具有sessionID的Cookie将放置在用户浏览器中
4. 在后续请求中,会根据数据库验证sessionID,如果有效,则接受请求
5. 一旦用户注销应用程序,会话将在客户端和服务器端都被销毁

基于令牌的认证流程:

1. 用户输入其登录信息
2. 服务器验证信息是否正确,并返回已签名的token
3. token储在客户端,最常见的是存储在`local storage`中,但也可以存储在session存储或cookie中
4. 之后的HTTP请求都将token添加到请求头里
5. 服务器解码JWT,并且如果令牌有效,则接受请求
6. 一旦用户注销,令牌将在客户端被销毁,不需要与服务器进行交互一个关键是,令牌是无状态的。后端服务器不需要保存令牌或当前session的记录。

哇标记听起来很酷。他们比基于session的身份验证更好吗?

问错人了,伙计。我只是告诉你存在这个验证方式。我不会比较没有意义的比较,我尽最大努力做到这一点。有关更多有趣的免责声明,请访问上面的免责声明部分。令牌的类型一些常见的令牌包括JWT(下面讨论),SWT(简单网络令牌)和SAML(安全断言标记语言)

链接

JWT

JWT代表“JSON Web Token”。 JWT是一种基于Token的认证。 JWT基于Web标准。现在JWT用的越来越多;JWT是Token认证的一种,所以说JWT基于Token的认证。再次,基于Token的认证的不同方法具有不同的优点和缺点。因此,上面的基于令牌的认证部分中的很多信息适用于此。

来自JWT RFC 7519标准化的摘要说明:JSON Web Token(JWT)是一种紧凑的,URL安全的方式,表示要在双方之间传输的声明。

JSON Web令牌是一个字符串。它可能看起来像这样:

eyJhbGciOIJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

上面的字符串是你在使用JWT执行身份验证时可能看到的;它是在认证时从服务器返回的凭证。JWT经过验证并且安全,因为它们使用私钥进行“数字签名”,并使用密钥进行身份验证。

JWT的结构?

JWT是一个自包含的数据块。每个JWT由 payloadsignature 组成。当您的服务器创建token时,您还可以为token分配唯一的数据,可以在前端使用。这可以用于保存稍后进行其他数据库调用的需要。你仍然应该警惕在发送给客户的令牌中发布机密信息(比如说用户密码等等)。

在Python中创建JWT令牌的示例函数:

def create_token(user):
    """Create a JWT token, set expiry, iat, etc"""
    payload = {
        ‘sub‘: user.id,
        ‘name‘: user.first_name,
        ‘role_id‘: user.role_id,
        ‘iat‘: datetime.utcnow(),
        ‘exp‘: datetime.utcnow() + timedelta(days=1)
    }
    token = jwt.encode(payload, MY_SECRET_KEY_SHHH_DONT_TELL_ANYONE, algorithm=‘HS256‘)
    return token.decode(‘unicode_escape‘)

上面的键sub,iat和exp跟随保留的JWT键,但我也添加了用户的名称和role_id。你将需要一个库来编码/解码JWT令牌。 JWT.io 列出了许多语言的库。

链接

OAuth

OAuth是一种认证协议,允许用户对没有密码的服务器执行认证。 OAuth存在很多版本 - OAuth 1.0,OAuth 1.0a和OAuth 2.0。

如果您曾使用Twitter,Google或Facebook帐户登录了某项服务,那么您已使用OAuth。

OAuth提供商(Facebook,Google等)通过提供您的服务(“OAuth客户端”)身份验证方式的私有,唯一的访问令牌,允许登录。

如果您要使用OAuth让用户登录您的服务,则需要将您的服务器注册为OAuth客户端。这通常会设置一个客户端ID和客户端密钥。登录到您的服务的用户将重定位到OAuth提供程序,用户可以在其中确认他们确实想要“登录”(即允许他们登录的服务器)访问OAuth提供程序的任何必需的信息。 )在我们的朋友Beorn的情况下...

在我们的朋友Beorn的情况下...

OWASP说:

建议使用OAuth 1.0a或OAuth 2.0,因为已发现第一个版本(OAuth1.0)容易受到session固定的影响。OAuth 2.0依靠HTTPS进行安全保障,目前OAuth的API(如Facebook,Google,Twitter和Microsoft)已经实现了。 OAuth1.0a很难使用,因为它需要使用用于数字签名的加密库。然而,由于OAuth1.0a不依赖HTTPS来实现安全性,因此它更适合于更高风险的事务。

链接

OpenId

OpenId是另一种不需要密码的身份验证协议(类似于OAuth)。 OpenId网站有一个非常简洁明了的描述,在我看来:

OpenID允许您使用现有帐户登录多个网站,而无需创建新密码。您可以选择将信息与您的OpenID相关联,以便与您访问的网站(例如姓名或电子邮件地址)共享。使用OpenID,您可以控制与您访问的网站共享的信息量。使用OpenID,您的密码仅提供给您的身份提供商,然后该提供商会确认您访问的网站的身份。除了您的提供商,没有网站曾经看到您的密码,因此您不需要担心一个不道德或不安全的网站危害您的身份。

虽然从2005年开始,最近(2014年-h),OpenId发布了OpenId Connect,这是一种“基于OAuth 2.0系列规范的可互操作身份验证协议”(源)

OpenId和OAuth有什么区别?

OpenId类似于OAuth,但有一些差异。类似地,OpenId依赖于与第三方(依赖方(您登录的站点))交互以提供认证凭证的身份提供商。

不同的是,您可以使用OAuth允许您登录的网站能够访问来自提供程序的数据。这听起来可怕和混乱,但这里有一个简单的例子:

链接

这里是Stack Overflow的登录页面的图片,它提供了许多不同的身份验证方法:

技术分享

评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!