登录和第三方授权(Cookie和Authorization)

1 登录和授权的区别

  • 登录:身份认证,即确认[你是你]的过程。比如你输入用户名和密码请求,向服务器确认[你是你]

  • 授权:由身份或持有的令牌确认享有某些权限(例如获取用户信息)【比如古代皇上有权利杀任何人,其他人要有权利杀人需要有尚方宝剑,皇上给我尚方宝剑是授权方,尚方宝剑就是一个令牌,我就是令牌的持有方】。

登录过程实质上的目的也是为了确认权限,直接把我的权限授予我自己,相比授权就少了令牌这个概念。

因此,在实际的应用中,多数场景下的[登录]和[授权]界限是模糊的。

目前,登录和授权有两种方式:CookieAutorization,它们都是添加在header中的属性。

2 Cookie

2.1 Cookie的工作机制

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 服务器需要客户端保存的内容,放在 set-cookie headers里返回,客户端会自动保存(客户端会将服务器返回给我的 set-cookie 原封不动的保存,并且也会将访问的 host 地址作为键也存到cookie中,下次访问同一个地址时就会携带存储在客户端的cookie一起发送请求)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 客户端保存的cookies,会在之后的所有请求里都携带进 cookie header里发回给服务器

  • 客户端保存cookie是按照服务器域名来分类的,例如 shop.com 发会的cookie保存下来以后,在之后向 games.com 的请求中并不会携带

  • 客户端保存的cookie在超时后会被删除、没有设置超时时间的cookie(称作 session cookie)在浏览器关闭后就会自动删除;另外,服务器也可以主动删除还未过期的客户端cookies

简单来说,客户端只处理对cookie的保存,在访问同一个服务器的时候将保存到本地的cookie给发过去就行了;cookie的计算和修改是有服务器处理。

cookie就是在客户端帮助服务端记录保存状态的工作机制

cookie在移动端目前基本只处理登录记录,在往后的时间可能会慢慢的被抛弃。

2.2 Cookie的作用

  • 会话管理:登录状态、购物车等

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
为什么需要 sessionid

假如你输入用户名密码登录了账户,服务器记录你已经登录了,然后又有其他人请求服务器想查询你的用户信息,因为请求是HTTP,HTTP是无状态的,此时没有 sessionid 服务器又查询到你当前已经登录了,然后就会处理请求结果返回信息。

没有 sessionid 是不安全的,sessionid 能记录哪个客户端登录了,客户端通过在cookie携带 sessionid 让服务器知道你是哪个客户端,让HTTP请求是有状态的。

客户端访问同一个服务器可以存储多个cookie,比如用户登录后存储了服务器在cookie返回的 sessionid,然后向服务器发送其他请求也返回cookie。在这里插入图片描述

  • 个性化:用户偏好、主题

比如客户端请求了蓝色主题,在下次访问其他页面时,服务器记录了客户端的主题就会给页面提供蓝色主题。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • Tracking:分析用户行为

在这里插入图片描述

上面是客户端访问 shop.com 时展示一个html页面。这个页面有一个图片 http://3rd-party.com/image.jpg,这张图片由第三方 3rd-party.com 提供。

你在这个图片的访问被记录了 from=shop.com 外链给第三方,这能让第三方公司 3rd-party.com 知道你是在 shop.com 查看了这张图片,第三方公司能跟踪到你的行为,并给你返回cookie让客户端保存。

下次你在其他网站展示图片,而图片同样来自 3rd-party.com,你就会携带当时第三方给你的cookie,并且让第三方再记录你在哪个网站的访问,第三方就会跟踪完善对你的分析,推荐给你需要符合的信息。

2.3 Cookie存在的问题(了解即可)

  • XSS(Cross-site scripting):跨站脚本攻击。即使用javascript拿到浏览器的cookie之后,发送到自己网站,以这种方式来盗取用户cookie

应对方式:HttpOnly。这个cookie只能用于HTTP请求,不能被javascript调用。它可以防止本地代码滥用cookie。客户端在HTTP请求时在cookie加上这个属性 Cookie:HttpOnly

  • XSRF(Cross-site request forgery):跨站请求伪造。即在用户不知情的情况下访问已经保存了cookie的网站,以此来越权操作用户账户(例如盗取用户资金)

应对方式:Referer校验,主要从服务器安全角度考虑。

3 Authorization

Authorization 授权有两种主流方式:

  • Basic

  • Bearer

3.1 Basic

Basic 用得比较少,但也是很有用。格式如下:

// HTTP header中添加
// 对username:password进行Base64作为header的授权
Authorization:Basic<username:password(Base64ed)>

GET /user HTTP/1.1
Host:xxx.com
Authorization:Basic xxxx

虽然Basic简单,但是有风险(不过是可避免的):

  • 使用的Base64(Base64是可逆的解码的),但是这可以通过HTTPS来解决,不完全是Basic的问题

  • token需要反复使用,那就要存在本地文件,如果手机被root了,有些恶意软件伪装成工具软件就有可能把token窃走,只能改密码

3.2 Bearer

Bearer 的授权流程还是要从OAuth2流程来说明。

格式如下:

// HTTP header中添加
Authrization:Bearer<barer token>

3.2.1 OAuth2流程(第三方授权)

OAuth2授权操作流程(以掘金申请授权github账户为例子,第三方网站:掘金,授权方网站:github):

  • 第三方网站向授权方网站申请第三方授权合作,拿到 client idclient secret

在这里插入图片描述

  • 用户在使用第三方网站时,点击授权按钮[通过github授权],第三方网站将页面跳转到授权方网站,并传入 client id 作为自己的身份标识
    在这里插入图片描述
    在这里插入图片描述
  • 授权方网站根据 client id,将第三方网站的信息和第三方网站需要的用户权限展示给用户,并询问用户是否同意授权
    在这里插入图片描述
  • 用户点击[同意授权]按钮后,授权方网站将页面跳转回第三方网站,并传入 Authorization code 作为用户认可的凭证
    在这里插入图片描述
  • 第三方网站将 Authorization code 发送回自己的服务器
    在这里插入图片描述
  • 服务器将 Authorization code 和自己的 client secret 一并发送给授权方的服务器,授权方服务器在验证通过后,返回 access token。OAuth流程结束
    在这里插入图片描述
// HTTP请求带上access token从github获取用户信息处理注册登录
GET /user HTTP/1.1
Host: github.com
Authorization: Bearer xxxx
  • 在上面的过程结束之后,第三方网站的服务器(或者有时客户端也会)就可以使用 access token 作为用户授权的令牌,向授权方网站发送请求来获取用户信息或操作用户账户。但这已经在OAuth流程之外

为什么用户点击授权按钮时要先拿到 Authorization code,然后把 Authorization code 发送给服务器后,再通过 Authorization code 获取到 access token,而不是用户点击授权按钮后直接返回 access token

其实是为了安全,Authorization code 不是token,而是用来获取token的。OAuth不强制授权流程必须使用HTTPS,通过 Authorization code 授权方github能判断是哪个第三方跟它获取 access token。因此需要保证当通信路径中存在窃听者时,依然具有足够高的安全性。

3.2.2 微信登录(第三方登录)

在这里插入图片描述

第三方App微信登录其实也是一个OAuth2流程:

  • 第三方App向腾讯申请第三方授权合作,拿到 client idclient secret

  • 用户在使用第三方App时,点击[微信登录],第三方App将使用微信sdk跳转到微信,并传入自己的 client id 作为自己的身份标识

  • 微信通过和服务器交互,拿到第三方App的信息,并限制在界面中,然后询问用户是否同意该App使用微信登录

  • 用户点击[使用微信登录]后,微信和服务器交互将授权信息提交,然后跳转回第三方App,并传入 Authorization code 作为用户认可的凭证

  • 第三方App调用自己服务器的[微信登录]API,并传入 Authorization code,然后等待服务器响应

  • 服务器在收到登录请求后,拿收到的 Authorization code 去向微信的第三方授权接口发送请求,将 Authorization code 和自己的 client secret 一起作为参数发送,微信在验证通过后,返回 access token

  • 服务器在收到 access token 后,立即拿着 access token 去向微信的用户信息接口发送请求,微信验证通过后,返回用户信息

  • 服务器在收到用户信息后,在自己的数据库中为用户创建一个账户,并使用从微信服务器拿来的用户信息填入自己的数据库,以及将用户的ID和用户的微信ID做关联

  • 用户创建完成后,服务器向客户端的请求发送响应,传送会刚创建好的用户信息

  • 客户端收到服务器响应,用户登录成功

上面是第三方App微信登录的流程。

在实际开发中,发现了一种错误的做法,服务器在拿到 access token 后,就把 access token 发给客户端,让客户端自己去授权方获取用户数据。这就把OAuth2的优势浪费了,Authorization code 就没用了,这样还是会泄露 access token这是错误的
在这里插入图片描述在这里插入图片描述

3.2.3 OAuth2流程简单总结

OAuth2流程简单说明:

  • 1、第三方网站持有授权网站给的 client idclient secret

  • 2、用户在第三方网站授权登录,跳转到授权网站提供 client id

  • 3、用户允许授权拿到 Authrization code 给第三方网站服务器

  • 4、第三方网站服务器把 Authrization codeclient secret 给授权网站拿到 access token

上面的流程客户端只需要做第2、3步即可,剩下的都是服务器处理。

上面虽然列出了第三方授权和第三方登录,但是要区分好两者:

在技术上,其实只有第三方授权,没有第三方登录。因为第三方登录是github授予权限给掘金,掘金就可以通过token拿到github的用户信息,通过这些信息在掘金自己的服务器处理注册登录账号。

第三方登录是基于第三方授权的,所以掘金在登录过程中它不是第三方,因为它是实际给你注册登录的;而在授权过程中它是第三方,因为它是被github授权的。

3.2.4 自家App中使用Bearer token

有的App会在API设计中,将登录和授权设计成类似OAuth2的流程,但简化掉 Authrization code 概念。即:登录接口请求成功时,会返回 access token,然后客户端在之后的请求中,就可以使用这个 access token 来当作 bearer token 进行用户操作了。

3.2.5 Refresh token

{
	"token_type": "Bearer"
	"access_token": "xxxxx"
	"refresh_token": "xxxxx"
	"expires_time": "xxxxx"
}

access_token 有失效时间,在它失效后,调用 refresh_token 接口,传入 refresh_token 来获取新的 access_token

提供 refresh token 主要是为了安全,可以做到以下处理:

  • access token 失窃,由于它有失效时间,因此坏人只有较短的时间来[做坏事]

  • 由于(在标准的OAuth2流程中)refresh token 永远只存在于第三方服务的服务器中,因此 refresh token 几乎没有失窃的风险

  • 12
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值