尽量把OAuth2.0的原理讲透透的
程序员文章站
2022-06-24 18:06:00
...
最近在补架构师图谱里的内容,OAuth2.0是其中一块,抽空看了几个文章,理解了一下。
不过我感觉多数文章都不是很直观,花费了好久才理解其中的过程,以及为什么要这么设计,也许里面还有一些为什么没搞清楚。
于是我试着写出来,用更好的方式来理解OAuth2.0。
一、OAuth2.0是什么
我们经常用某些公众号,用一些论坛,有用QQ,微信登录什么的,需要你在QQ,微信的界面上授权,这些号、论坛就可以拿到你的个人信息,头像什么的,但他们没有你的用户密码。
生活中,我去银行办理过代扣水电煤,银行确认我的身份,然后签一个代扣合同,给我回执,之后水电煤公司就直接从我的账户划钱过去了。但公司不知道我的密码,不能代做其它没授权的操作。
差不多上OAuth2.0就是解决上面的问题。
二、如果我来设计OAuth2.0,怎么设计?
先设想一个场景:我有银行账户,想授权朋友查看账户金额,不告诉他密码,应该怎么办?
我和朋友去银行,银行先后验证我们俩的身份证。银行让我签一个授权合同,上面写着我授权朋友查我的账户,银行给我和朋友各一份合同凭证。银行后台登记朋友拿这个凭证可以查我的账户这样一条信息。之后朋友拿着凭证和他自己的身份证,果然查到了我的账户信息。
上面的分析蛮简单的,貌似也没有什么问题。朋友不可能转账,因为银行会查授权合同,我的合同被其它人知道了,别人也不可能查我的账户,因为只授权给朋友。
那么把上面的过程转化到应用之中去。
三、标准的认证过程
OAuth认证和授权的过程如下:
1、用户访问第三方网站网站,想对用户存放在服务商的某些资源进行操作。
2、第三方网站向服务商请求一个临时令牌。
3、服务商验证第三方网站的身份后,授予一个临时令牌。
4、第三方网站获得临时令牌后,将用户导向至服务商的授权页面请求用户授权,然后这个过程中将临时令牌和第三方网站的返回地址发送给服务商。
5、用户在服务商的授权页面上输入自己的用户名和密码,授权第三方网站访问所相应的资源。
6、授权成功后,服务商将用户导向第三方网站的返回地址。
7、第三方网站根据临时令牌从服务商那里获取访问令牌。
8、服务商根据令牌和用户的授权情况授予第三方网站访问令牌。
9、第三方网站使用获取到的访问令牌访问存放在服务商的对应的用户资源。
四、对比一下二与三
【2.第三方网站向服务商请求一个临时令牌】,也就是论坛自己也登录一下,比如被QQ认证一下。
【7.第三方网站根据临时令牌从服务商那里获取访问令牌。】,临时令牌只是论坛的身份,而访问令牌是临时令牌与授权码的组合。
有没有可能授权后,直接返回给网站【访问令牌】呢?
貌似也可以,这时候服务商页面把这个访问令牌发到网站的返回地址了,但用户是不是可以从浏览器里看到从QQ发给论坛的内容呢?如果用户再把这个POST内容给了其它地方,好像可以诬陷网站呢。
如同最初银行里,银行可以给朋友一个超级码,朋友以后可以不被验身份只凭这个码查询。但这个码是不能给我看到的。
浏览器做不到不给我看,这个访问令牌是不可以给用户看到的,给大家都看到的只是授权码。
有没有可能服务商后台悄悄把【访问令牌】给网站呢?那一开始就要传给服务商两个地址了,一个是悄悄给网站令牌的地址,一个是返回给用户显示的网站的地址了,更麻烦了。
上面的解释是不是更清楚呢?从生活中来思考软件上的实现,一方面不容易忘记整个过程,另一方面有助于自己设计开发一些复杂的场景。
五、引伸
1.回过头再看支付过程。
从生活中设想场景,与上面的OAuth2.0是非常的相似。比如生活中,我在商家购买东西,可以一起进银行,银行验证我的身份,验证商家身份。再由我签字认可划钱给商家就结束了。没有了最后一个步骤,比上面还简单一点。
在电商中,就是我和商家都是某平台的用户,在商家买好了,跳转到平台,商家要传订单信息与付款金额以及自己的认证信息过去。平台确认商家信息后,显示我的登录页面和授权转钱给商家的页面,我不同意就付款失败,我同意了就转账并跳转到商家的成功页面。当然商家会另外查询成功或者是失败的。
2.从生活场景理解KAFKA帮助记忆
2.1 KAFKA分布式的、可分区、可复制的消息系统。
基本术语:
2.2 上述过程可理解为:
一个主题topic比如是一个元帅,下面有10个信使(10个partition),每个人都传元帅的消息命令,每个信使都有一个小跟班(复制1份备用)。
每个信使传2个命令给5个部队的主要将军们(5个消费者群),但信使们要过3个独木桥,每个只能选一个桥过。信使与小跟班分过不同的桥(broker),以防止意外。
那么一个桥上有平均7个信使或者跟班。但同一个信使与跟班一定在不同的桥上,防止桥断了的情况下消息与备份都消失。桥宽窄不同,不同的信使通过速度不同。但同一个信使的人个消息有先后。
5个部队都要收够10个信使(桥断了就是对应的跟班)的信息,共20条信息。
5个部队的将军们分头在不同的桥头接着消息。来自同一个部队的将军们中只能有一个收同一个信使的消息,否则这个部队中两个将军收到同一个信使消息的话,对这个部队来说就有重复了(不知是部队记录消息重复,还是信使记录是否某个部队收过了?应该是后者,信使如果又碰到同一部队的将军就不给他消息了)。
5个部队各自都要收齐所有10信使的20个消息。每个信使都要确保手上的消息给了5个部队。
2.3上面要记录的一些信息,比如消费者群里的消费者,都记录在zookeeper这个分布式事务协调器中,树弄结构,动态的都对应临时节点。比如:
不过我感觉多数文章都不是很直观,花费了好久才理解其中的过程,以及为什么要这么设计,也许里面还有一些为什么没搞清楚。
于是我试着写出来,用更好的方式来理解OAuth2.0。
一、OAuth2.0是什么
我们经常用某些公众号,用一些论坛,有用QQ,微信登录什么的,需要你在QQ,微信的界面上授权,这些号、论坛就可以拿到你的个人信息,头像什么的,但他们没有你的用户密码。
生活中,我去银行办理过代扣水电煤,银行确认我的身份,然后签一个代扣合同,给我回执,之后水电煤公司就直接从我的账户划钱过去了。但公司不知道我的密码,不能代做其它没授权的操作。
差不多上OAuth2.0就是解决上面的问题。
二、如果我来设计OAuth2.0,怎么设计?
先设想一个场景:我有银行账户,想授权朋友查看账户金额,不告诉他密码,应该怎么办?
我和朋友去银行,银行先后验证我们俩的身份证。银行让我签一个授权合同,上面写着我授权朋友查我的账户,银行给我和朋友各一份合同凭证。银行后台登记朋友拿这个凭证可以查我的账户这样一条信息。之后朋友拿着凭证和他自己的身份证,果然查到了我的账户信息。
上面的分析蛮简单的,貌似也没有什么问题。朋友不可能转账,因为银行会查授权合同,我的合同被其它人知道了,别人也不可能查我的账户,因为只授权给朋友。
那么把上面的过程转化到应用之中去。
- 我在某论坛上操作,希望用QQ登录。(论坛认为我有QQ号的,论坛本身也在QQ注册过自己的应用的。就如同去银行,这个银行必须可以鉴定我们双方的身份。)
- 点了QQ登录,那论坛就引导跳转到QQ的授权页面了。(这个过程中,论坛必须提供了自己的登录信息,QQ那边认证了,才出现授权页面。)
- 在这个页面里,我要登录一下QQ了。前面已经认证过论坛了,现在登录就是认证我了。
- 登录成功后,QQ显示出授权的内容,让我确认,我点了确认。(类似银行让我签授权合同了)
- 确认之后,按说是银行将确认了的授权合同,一式三份,给我和论坛各一份。给我看合同并不重要,可以后台存下来,我随时可以登录后,在已授权的地方查看给过的授权信息。关键是怎么给论坛?
- 事实上论坛当初转到QQ授权页面的时候,除了提供自己的身份,还有一个redirectUrl。当我点了授权后,QQ把合同给了这个Url,等于就是给了论坛了。
- 论坛拿到了合同,再把自己的登录信息给QQ再验证一下,QQ就把我的资料给了论坛了。如果这里不再验证论坛的身份,论坛把合同卖给其它地方怎么办?那就不安全了!当然我也可能把合同转给其它地方用,来陷害是这个论坛在用。
三、标准的认证过程
OAuth认证和授权的过程如下:
1、用户访问第三方网站网站,想对用户存放在服务商的某些资源进行操作。
2、第三方网站向服务商请求一个临时令牌。
3、服务商验证第三方网站的身份后,授予一个临时令牌。
4、第三方网站获得临时令牌后,将用户导向至服务商的授权页面请求用户授权,然后这个过程中将临时令牌和第三方网站的返回地址发送给服务商。
5、用户在服务商的授权页面上输入自己的用户名和密码,授权第三方网站访问所相应的资源。
6、授权成功后,服务商将用户导向第三方网站的返回地址。
7、第三方网站根据临时令牌从服务商那里获取访问令牌。
8、服务商根据令牌和用户的授权情况授予第三方网站访问令牌。
9、第三方网站使用获取到的访问令牌访问存放在服务商的对应的用户资源。
四、对比一下二与三
【2.第三方网站向服务商请求一个临时令牌】,也就是论坛自己也登录一下,比如被QQ认证一下。
【7.第三方网站根据临时令牌从服务商那里获取访问令牌。】,临时令牌只是论坛的身份,而访问令牌是临时令牌与授权码的组合。
有没有可能授权后,直接返回给网站【访问令牌】呢?
貌似也可以,这时候服务商页面把这个访问令牌发到网站的返回地址了,但用户是不是可以从浏览器里看到从QQ发给论坛的内容呢?如果用户再把这个POST内容给了其它地方,好像可以诬陷网站呢。
如同最初银行里,银行可以给朋友一个超级码,朋友以后可以不被验身份只凭这个码查询。但这个码是不能给我看到的。
浏览器做不到不给我看,这个访问令牌是不可以给用户看到的,给大家都看到的只是授权码。
有没有可能服务商后台悄悄把【访问令牌】给网站呢?那一开始就要传给服务商两个地址了,一个是悄悄给网站令牌的地址,一个是返回给用户显示的网站的地址了,更麻烦了。
上面的解释是不是更清楚呢?从生活中来思考软件上的实现,一方面不容易忘记整个过程,另一方面有助于自己设计开发一些复杂的场景。
五、引伸
1.回过头再看支付过程。
从生活中设想场景,与上面的OAuth2.0是非常的相似。比如生活中,我在商家购买东西,可以一起进银行,银行验证我的身份,验证商家身份。再由我签字认可划钱给商家就结束了。没有了最后一个步骤,比上面还简单一点。
在电商中,就是我和商家都是某平台的用户,在商家买好了,跳转到平台,商家要传订单信息与付款金额以及自己的认证信息过去。平台确认商家信息后,显示我的登录页面和授权转钱给商家的页面,我不同意就付款失败,我同意了就转账并跳转到商家的成功页面。当然商家会另外查询成功或者是失败的。
2.从生活场景理解KAFKA帮助记忆
2.1 KAFKA分布式的、可分区、可复制的消息系统。
基本术语:
- broker:一个kafka集群由一个或者多个broker组成;
- topic:Kafka中用来维护的一类消息;
- partition:每个topic包含多个分区,每一个分区都存在各个broker中,但是一个分区只选取一个broker作为主节点;
- producer:生产并发送消息到Kafka topic中;
- consumer:消息消费者;
- consumer group:每个consumer属于一个特定的consumergroup,对于一个topic中的消息只能被同一个group下的一个consumer消费。
2.2 上述过程可理解为:
一个主题topic比如是一个元帅,下面有10个信使(10个partition),每个人都传元帅的消息命令,每个信使都有一个小跟班(复制1份备用)。
每个信使传2个命令给5个部队的主要将军们(5个消费者群),但信使们要过3个独木桥,每个只能选一个桥过。信使与小跟班分过不同的桥(broker),以防止意外。
那么一个桥上有平均7个信使或者跟班。但同一个信使与跟班一定在不同的桥上,防止桥断了的情况下消息与备份都消失。桥宽窄不同,不同的信使通过速度不同。但同一个信使的人个消息有先后。
5个部队都要收够10个信使(桥断了就是对应的跟班)的信息,共20条信息。
5个部队的将军们分头在不同的桥头接着消息。来自同一个部队的将军们中只能有一个收同一个信使的消息,否则这个部队中两个将军收到同一个信使消息的话,对这个部队来说就有重复了(不知是部队记录消息重复,还是信使记录是否某个部队收过了?应该是后者,信使如果又碰到同一部队的将军就不给他消息了)。
5个部队各自都要收齐所有10信使的20个消息。每个信使都要确保手上的消息给了5个部队。
2.3上面要记录的一些信息,比如消费者群里的消费者,都记录在zookeeper这个分布式事务协调器中,树弄结构,动态的都对应临时节点。比如:
- Broker node 注册 ls /broker/ids/[0...N]-->broker的id,唯一不重复。
- Broker Topic 注册 ls /broker/topics/[topic]/partitions/[0...N]-->partition索引号
- Consumer id 注册 ls /consumers/[group_id]/ids/[consumer_id]-->consumer的id
- Consumer offset 跟踪 get /consumers/[group_id]/offsets/[topic]/[partition_id]-->offset值
- Partition Owner 注册 get /consumers/[group_id]/owners/[topic]/[partition_id]--->consumerId
推荐阅读