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

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

本文档的目的是记录和编目Web上的身份验证方法。
认证指的是创建一个系统的过程,用户可以通过该系统“登录”在线服务,并授予对受保护资源的访问权限。
以下引用可能更好地总结我想要解释的内容:

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

How

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

免责声明:本文档不作为包含所有认证方法的网络的目录;
本文档也不旨在提供“最佳”认证方法。
没人给钱贿赂我。
如果你想赞助我那更棒, 可以用一些其它方式, 比如领养一只小狗,或者帮助正在辛劳的人们。

引文:这些引文表示我引用的来源。
如果你想让我收下链接/更好地引用我的来源(不仅仅是一个链接到原始发布),我可以这样做。
如果你想让我更好的引用引文, 我当然愿意,不过请先让我知道<3。

遗漏,错误:
犯错并不罕见,我并不是安全方面的专家
如果你看到一些可以改进的东西请PR,告诉我哪里弄错了,我可以改进。
有关PR更多的信息,请查看CONTRIBUTIONS.md。

假想案例

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

我们的例子将会有一个想象的朋友:Beorn。
Beorn喜欢针织,经常去http://knittingworld.com购买用品。
Beorn在knittingworld有一个帐号,我们将看到他登陆的例子。

一般最佳做法

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

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

  • 切勿将密码存储为数据库中的纯文本。

  • 不要写自己的哈希算法(除非你真的很聪明)

  • 不要写自己的认证技术(再次,除非你真的很聪明)。

  • 使用HTTPS。

一些忠告

我们还发现许多网站设计自己的身份验证机制,以提供更好的用户体验。不幸的是,设计师和实现者通常没有安全背景,因此不能很好地理解他们可以使用的工具[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关闭游览器重新再打开后:

  • Beorn去http://knittingworld.com 买纱线。

  • 在挑选出纱线后,他点击“购买”按钮购买。

  • 他的浏览器发出一个GET请求,服务器响应401告诉他需要验证。

  • Beorn在他的用户名和密码中输入登录表单。

  • 在他点击登陆后,他的浏览器会发起GET(POST)请求, 并在请求头里带着Authorization。Authorization请求头类似于这样Authorization:QWxhZGRpbjpvcGVuIHNlc2FtZQ==

  • 服务器继续验证身份验证头并确定Beorn是否可以可以提交购买操作。浏览器会记住Authorization,之后的每一次游览器提交的请求,都会在请求头里加上Authorization:QWxhZGRpbjpvcGVuIHNlc2FtZQ==, 直到游览器关闭。

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

  • 上面的示例授权头部看起来不像用户名和密码,但是这是因为它是base64编码。它没有加密。

  • 如果使用HTTP基本认证,请使用HTTPS。如果使用HTTP,身份验证凭据将作为明文发送到服务器。这不好。用户的用户名和密码通过线路仅作为base64编码文本发送 - 这对于解码来说很简单。通过使用HTTPS / TLS,您确保从客户端发送到服务器的数据被加密。

  • HTTP基本验证由游览器实现,今天很少使用。

  • 基本验证使用API​​的基本认证,当与令牌组合时,(稍后讨论)只是一个授权报头,是完全合理的。它有额外的好处,不需要API客户端维护一个额外的会话cookie,并且,因为大多数系统日志查询参数而不是标题,将不会被默认记录。

  • 基本验证与Token组合的时候, 好处很多,比如不需要客户端单独维护一个cookie, 并且也不会被客户端记录。

链接

基于Session的认证

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

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

  • Beorn去http://knittingworld.com 买一些东西。

  • 当Beorn登录时,他将他的凭据发送到服务器。

  • 当凭据到达服务器时,服务器以这种方式或另一种方式需要检查Beorn是否是其数据库中的用户。在这一点上,Beorn还没有登录。

  • Beorn的凭据匹配成功,所以他可以登录。

  • Beorn需要一些东西来识别他对服务器的未来请求 - 特别是如果他想要购买东西(必须登陆才能买)。这就是认证session的思想。

  • 现在服务器知道Beorn是谁,并且已经将他识别为数据库中的用户,服务器将向他(或“返回”)发送一个cookie,这可以将Beorn列为在以后的请求中是已经登陆的用户。

  • 现在,Beorn已经验证,并在他的浏览器上有一个session cookie(cookie的一种)。

  • 当Beorn转到页面http://knittingworld.com/great_deals.html 他正在做另一个HTTP请求 - 但这次,他的session cookie将放在HTTP请求头里发送到服务器。

  • 服务器将根据与内存中Session信息匹配的cookie进行身份验证(可以用redis,memcache等数据库来保存)

  • 当Beorn从http://knittingworld.com 退出时,他在服务器(或Redis等)上的会话实例将过期,他的会话cookie也会过期。

基于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列出了许多语言的库。

链接w

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的情况下...

  • Beorn去http://knittingworld.com 买东西。

  • Beorn决定使用他的Google帐户登录。

  • 提示Beorn输入他的google帐户信息(如果他还没有登录

  • 输入信息后,Google(或者其它的OAuth提供商)将提示他是否要使用他的Google帐户登录http://knittinggworld.com 。

  • 接受后,Beorn被重定向到http://knittingworld.com 。

  • 如果knittingworld需要访问关于Beorn信息的资源,它可以向资源服务器(通过OAuth提供者)请求访问它们,只要它的token是有效的。

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允许您登录的网站能够访问来自提供程序的数据。这听起来可怕和混乱,但这里有一个简单的例子:

    • Beorn注册为twitter。他要推销他编织的帽子

    • Beorn不知道follow谁,没有人follow他。 Beorn悲伤的感觉不重要。

    • Twitter提示Beorn使用OAuth连接他的Google帐户,以便他可以导入他的联系人到Twiiter。

    • Beorn follow了一群人,包括来自他多年没有见过的高中的老朋友

    • Beorn这样做了,现在他正在不停地tweeting。

认证 协议 JWT OAuth Session Cookie的更多相关文章

  1. 记录:http协议+response+request+session+cookie

    1.http协议 http协议也叫作超文本传输协议,定义了浏览器向怎样向服务器请求资源和服务器怎样将资源传给浏览器.http协议是面向事务的应用层协议,是万维网能够传递资源的可靠保障. 目前http协 ...

  2. jwt、session、oauth 异同

    1,jwt 和session机制 首先jwt 和session机制 都是用户认证的,oauth 不是 session 的流程: 1.用户向服务器发送用户名和密码. 2.服务器验证通过后,在当前对话(s ...

  3. ASP.NET Core Web Api之JWT VS Session VS Cookie(二)

    前言 本文我们来探讨下JWT VS Session的问题,这个问题本没有过多的去思考,看到评论讨论太激烈,就花了一点时间去研究和总结,顺便说一句,这就是写博客的好处,一篇博客写出有的可能是经验积累,有 ...

  4. OAuth认证协议原理分析及同步消息到Twitter和Facebook使用方法

    OAuth有什么用?为什么要使用OAuth? twitter或豆瓣用户一定会发现,有时候,在别的网站,点登录后转到 twitter登录,之后转回原网站,你会发现你已经登录此网站了,这种网站就是这个效果 ...

  5. http协议。会话控制cookie、session

    http协议是无状态的协议.每次访问页面的http协议都是独立的,正是因为http协议是无状态的,所以导致访问一个页面后再去访问另一个页面的时候,一些数据会消失,比如:用户的登录信息就会消失.那么怎么 ...

  6. JWT,oAuth和SSO的讨论

    JWT,oAuth和SSO的讨论 背景 Single Sign On有很多成熟的方案.基于Session的服务常使用缓存Session信息在一个缓存服务上(例如redis)以实现SSO,每个微服务使用 ...

  7. JWT与Session比较和作用

    1. JSON Web Token是什么 JSON Web Token (JWT)是一个开放标准(RFC 7519),它定义了一种紧凑的.自包含的方式,用于作为JSON对象在各方之间安全地传输信息.该 ...

  8. Session Cookie Token Json-Web-Token

    什么是认证(Authentication) 通俗地讲就是验证当前用户的身份,证明"你是你自己"(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就 ...

  9. 程序员过关斩将--更加优雅的Token认证方式JWT

    菜菜,上次你讲的cookie和session认证方式,我这次面试果然遇到了 结果怎么样? 结果面试官问我还有没有更好的方式? 看来你又挂了 别说了,伤心呀.到底还有没有更好的方式呢? 你猜? 基于To ...

随机推荐

  1. 计算某个时间段(2017-10-01 2017-12-01)内svn更新文件的MD5

    #!/bin/sh svn up svn log -v -r {$1}:{$2} | grep / | grep -v xxx | sort -f -u | uniq | awk -F 'xxxx' ...

  2. Android 概览屏幕

    文章照搬过来的:原文地址https://developer.android.google.cn/guide/components/recents.html 概览屏幕(也称为最新动态屏幕.最近任务列表或 ...

  3. C语言笔记(二)

    注释 编译器会用空格代替代码中原来的注释,并先于预处理指令执行/*…*/ 这种形式的注释不能嵌套只要斜杠(/)和星号(*)之间没有空格,都会被当作注释的开始.例如这样:y = x/*p; \ 是一个接 ...

  4. hibernate_07_单表操作_增删改操作

    首先,创建类对象 package com.imooc.hibernate; public class Address { private String postcode; //邮编 private S ...

  5. C#自动缩进排列代码的快捷键 c# 代码重新排版 变整齐

    C#自动缩进排列代码的快捷键:  ctrl + k + d 1.小技巧, 可以把最后一个}去掉, 重新写下,就可以达到排版的效果. 2.快捷键:编辑-高级-设置文档的格式 快捷键Ctrl+E,D,设置 ...

  6. C#访问Win 32的一些尝试

    使用C#调用Win 32 Api大部分情况下基本只涉及到参数类型的转变,但在遇到Win 32 Api返回LPVOID *lpBuff 时会遇到一些解析遍历难题.lpBuff为二维指针,*lpBuff是 ...

  7. POJ_2115_扩展欧几里德

    C Looooops Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 23673   Accepted: 6540 Descr ...

  8. HDU_5833_高斯消元

    参考自:http://www.cnblogs.com/flipped/p/5771492.html 自己做的时候不知道如何求种数.看了题解,感觉思路灰常巧妙.同时也感觉这是一道好题. 精髓在于转化为线 ...

  9. 判断input或者div.span等标签是否存在

    //用jQuery检查某个元素在网页上是否存在时,应该根据获取元素的长度来判断,代码如下 if($("#email"+i).length > 0){//判断input是否存在 ...

  10. 我理解的数据结构(三)—— 队列(Queue)

    我理解的数据结构(三)-- 队列(Queue) 一.队列 队列是一种线性结构 相比数组,队列对应的操作是数组的子集 只能从一端(队尾)添加元素,只能从另一端(队首)取出元素 队列是一种先进先出的数据结 ...