auth

常见的认证方案

1. HTTP Auth Authentication

这是HTTP提供的一个用于权限控制和认证的通用框架,其中最常用的HTTP认证方案就是HTTP Basic Authentication

[ 鉴权流程 ]
客户端发送一需要权限验证的请求,服务端返回未授权,需要授权。
客户端发送带有认证信息的请求,服务端验证并返回结果。

[ 加解密过程 ]

// 加密过程
let email = 'demo@test.com'
let password = '1234455'
let auth = `${email}:${password}`
const buf = Buffer.from(auth, 'ascii')
console.info(buf.toString('base64'))
// 解密过程
const buf = Buffer.from(authorizaiton.split(' ')[1] || ''), 'base64')
const user = buf.toString('ascii').split(':')

[ 其他HTTP认证 ]
基于HTTP身份验证框架的方案有多个,它们的安全强度不同有所不同。
常见的验证方案包括:

  • Basic(RFC 7616, Base64编码凭证)
  • Bearer(RFC 6750, bearer令牌通过OAuth2.0保护资源)
  • Digest(RFC 7616, 只有md5散列在Firefox中支持)
  • HOBA(RFC 7486, HTTP Origin-Bound认证,基于数字签名)
  • Mutual
  • AWS4-HMAC-SHA256

就先抄过来认个名儿吧!


2. Cookie + Session

用户在注册时提交用户名和密码,后端将密码“加盐”后存入数据库。

[ 鉴权流程 ]
用户提交用户名密码
服务端计算该用户SHA256并验证,若验证通过,为其创建一个Session对象,并将session_id用setCookie返回给浏览器
浏览器将session_id存到Cookie中,之后每次请求都带上Cookie
服务端收到带有session_id的request,根据session_id确定当前请求的用户,返回其请求数据。

[ Session存储 ]
常用的Session存储方式是键值对存储(KV存储),例如Redis,which在分布式、API支持、性能方面表现较好。其他的还有mysql, file存储等。

如果服务是分布式的,使用file存储的话,就存在多个服务间的同步问题,以及高并发情况下的读写锁控制问题。

[ Session刷新 ]
不能等到Session到期后就把用户踢下线,用户的操作要更新Session的存活时间。
但频繁的更新Session会影响性能,可以再session快过期的时候再更新expire
用户频繁操作将会导致sid长期有效, 这使得cookie更容易泄露,泄露时间更长,可以在生成sid的时候同时生成refreshId,用来在sid过期后请求新的sid(在这种模式下,用户操作不延长sid有效期),这要求前端判断sid失效并主动使用refreshId请求new_sid.

[ 单设备登录 ]
服务端建立起用户唯一标识与sessionId的对应关系,同一用户只能有唯一session,若多设备登录,可返回不允许登录或者挤掉之前登录用户。(默认情况下是可以多设备登录的)

3. JWT(Json Web Token)

[ 简介 ]
JWT是一个开发标准(RFC 7519),它以JSON对象传递信息,自包含,具有数字签名。

[ JWT组成 ]
header + payload + signature,以小数点分隔

UzI1NiIsInR5cCI.qaWUiLCJpYX.jRDjF4JfZcmq

上面只是个样子,真正Base64太长了,不好看

解码后:

// header
{"alg": "HS256", "type": "JWT"}

// payload
{"name": "demo", "iat": "1604737078045", "expire": "1604837078045"}

// signature
const encodedHeader = base64Encode(header)
const encodedPayload = base64Encode(payload)
const signature = HMACSHA256(encodedHeader + '.' + encodedPayload, '密钥')

[ 鉴权流程 ]
用户提交用户名密码
服务端计算SHA256验证通过,使用密钥创建JWT并放入set-Cookie
浏览器发送请求时带上JWT
服务端验证JWT,验证通过,根据 JWT payload获取用户信息,根据用户信息返回所请求数据。

[ Token校验 ]
服务端根据encodedHeader, encodedPayload以及密钥计算出signature与请求携带的JWT进行对比,若部分相等,则其是一个有效的JWT。

[ Token刷新 ]
同样地,为减少JWT泄露风险,一般会设置较短的有效期,不可能让用用户频繁登录去获取新的JWT
可以在生成JWT同时生成Refresh Token,用于请求新的JWT,Refresh Token只能使用一次。


4. OAuth

OAuth (Open Auth) 是一个开发标准,允许用户让 third-party app 访问某一网站下的 private resource,而不需要将用户名密码提供给第三方。

[ 授权流程 ]
登录京东商场时,选择“使用微信号登录”,页面跳转到微信页面,“京东商城”想要访问你的个人信息,你是否同意?
同意!微信给京东一个授权码
京东使用授权码请求你微信中的数据信息

[ OAuth其他模式 ]

  • 简化模式(Implicit grant type)
  • 密码模式(Resource Owner Password Credentials Grant)
  • 客户端模式(Client Credentials Grant)

其中,简化模式适用于纯前端应用,直接向前端颁发令牌;密码模式指的是:对于高度信任的应用,可以将用户名密码告诉该应用,它就可以直接使用密码申请令牌了;客户端模式适用于没有UI的命令行应用。

[ 单点登录 }
单点登录(Single Sign On)指的是登录某个网站一次,就可以直接访问其域名/旗下其他服务而不需要再登录。


总结

[ HTTP Auth ]
适用于内部安全性不高的系统上,例如路由器网页管理接口
存在问题:

  • 请求携带验证信息,容易被嗅探到
  • 无法注销
  • 适合一次性验证,例如注册连接激活

[ Cookie+Session ]
适用于传统系统独立鉴权
梳理:

  • 服务端存储session,客户端存储cookie,cookie保存的是sid
  • 可以灵活revoke权限,更新信息后可以方便地同步session中相应内容
  • 分布式session一般使用redis或其他KV存储

[ JWT ]
优点:

  • 服务端不需要存储session,方便扩展
  • JWT不依赖Cookie,可以通过HTTP header传递
  • 为减少盗用,使用HTTPS传输

适用于做简单的 RESTful API 认证和一次性验证,例如注册激活链接。
问题:

  • 有效期内Token一直有效,无法中途废弃
  • payload信息更新时,已下发token无法同步

[ OAuth ]
OAuth是一个开发标准,允许用户授权第三方应用使用其其他App的个人信息而不提供用户名和密码
分为四种模式:

  • 简化模式:不安全,适用于纯静态页面应用
  • 授权码模式:功能完善,流程严密的授权模式,通常使用在公网开放平台
  • 密码模式:一般在内部系统中使用,调用者以用户为单位
  • 客户端模式:一般在内部系统之间的API调用。两个平台之间调用,以平台为单位。

本文学习源全栈修仙之路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值