登录认证和鉴权

登录认证和鉴权

登录认证的应用场景很广泛,例如用户登录微信之后才能发起聊天,看朋友圈;登录支付宝之后才能进行支付等等。这些场景涉及用户权限,所以系统要知道当前用户是谁,以及用户有没有操作权限,那么具体怎么实现呢?

1.身份识别(Identification)

首先,需要识别用户身份。即根据用户所持有的识别信息,确认用户身份。

在现实生活中,我们用身份证来识别每个人的身份。例如在酒店办理入住时,用户需要出示身份证确认身份。在软件系统中,有哪些识别信息可以确认用户身份呢?

身份识别一般发生在登录过程,常见的有以下几种:

  1. 账号密码登录

    账号用来告诉系统我是谁,密码用来证明我是谁。

  2. 手机/邮箱验证码登录

手机/邮箱号用来告诉系统我是谁,验证码用来证明我是谁,因为只有当前用户的手机/邮箱才能收到验证码

用户 应用 SMS 用户输入手机号,请求验证码 生成一个跟手机号关联的验证码 把手机号和验证码发给短信服务平台 操作响应 操作响应 发送验证码 操作响应 用户输入验证码,请求登录 验证手机号和验证码 返回登录结果 用户 应用 SMS
  1. 手势/指纹/语音

跟账号密码类似,手势/指纹/语音就是身份识别信息。

2.授权(Authorization)

识别出用户身份之后,系统就可以赋予用户操作权限,即授权。

例如,用户在酒店办理入住手续后,就会拿到一张房卡,获得进出房间的权限。

在软件系统中,用户登录之后拿到访问令牌,获得访问系统的权限。

3.鉴权(Authentication)

用户获得授权后就可以执行操作了。用户每次执行操作时,系统会对用户权限的有效性进行鉴别,即鉴权。

例如,用户刷卡进入房间时,酒店的门禁系统会对房卡的有效性进行鉴别。

在软件系统中,系统也会鉴别每个请求的访问令牌的有效性。

小结

登录认证和鉴权的核心原理包括身份识别授权鉴权。这三者是顺序发生的,其中,身份识别和授权一般发生在登录过程,鉴权则发生在登录后的每次请求。

了解了登录认证和鉴权的核心原理,那么软件系统的鉴权方案该如何设计呢?

鉴权方案

1.Session鉴权

完成登录认证之后,服务端会创建一个Session结构来保存前后端的会话状态,并返回Session id给客户端,即授权。下次请求时,客户端携带Session id访问,服务端通过Session id获取会话状态并验证请求的有效性,即鉴权。

image.png

特点:

Session鉴权把会话状态保存在服务端,方便实时管理会话状态(注销登录/延长有效时间),但也带来了存储开销。

2.Token鉴权

完成登录认证之后,服务端给客户端签发一个访问令牌Token,即授权。下次请求时,客户端携带Token访问,服务端只需要校验Token的有效性即可,即鉴权。

image.png

Token的组成:

  • 用户信息
    token自身携带了用户的身份和状态信息(不含敏感信息),通常用一个JSON结构来保存。
{"userId":"2023031811211100",role:"admin"}
  • 有效时间
    token一但签发就不可撤销,所以必须设置一个有效时间。
{"userId":"2023031811211100", role:"admin", expire:"20230318113610"}
  • 防篡改
    为了防止token信息被篡改或伪造,对token进行签名验证(非对称加密)。

综上所述,Token由三部分组成:

1.标识签名算法
header = {"alg":"HS256","typ":"JWT"}
2.存储用户信息和有效时间等业务数据
payload = {"userId":"2023031811211100", role:"admin", expire:"202303181136"}
3.签名信息
signature = 签名算法("服务器私钥",payload)

其实,上面介绍的就是常用的Token方案–JWT(JSON Web Token)

特点:

  • Token本身携带身份状态信息,不需要存储在服务端。
  • Token一旦签发就不可撤销。
  • Token验签时有计算损耗。

小结

Session和Token是常用的鉴权方案。两者最大的区别是Session把会话状态保存在服务端,方便实时管理会话状态(注销登录/刷新有效时间)。Token自身携带了身份状态信息,不需要每次都去查询数据库。但是,Token一旦签发就不可撤销,并且Token验签时有计算损耗。

客户端一般使用Cookie或WebStorage来存储Session id/Token,但是服务端直接从Cookie校验Session id/Token会有CSRF风险,应该使用HTTP header代替。

登录方案

在前面已经介绍过最基本的登录方案了,例如账号密码登录和手机验证码登录,这些都是面向单个系统的场景。但实际应用中还有更复杂的场景,例如用户在同一应用下的多个子应用操作时,如何避免多次登录如何在不提供用户登录账号密码的情况下,登录第三方应用

1. 单点登录(Single Sign On)

用户在同一应用下的多个子应用操作时,需要多次登录,太麻烦了。我们希望用户只需登录一次,就可以访问其它互相信任的应用,即单点登录(SSO)。例如登录了淘宝,再去访问天猫时就不用再次登录。

解决方案就是建立一个公共的认证中心(CAS)。用户在CAS登录或注销后,CAS会将登录状态同步给所有子应用,实现子系统间共享登录状态。具体登录认证过程如下:

客户端 系统A CAS 访问系统A 本地会话(sessionA)鉴权失败,需要登录 302CAS登录页面+登录回调地址 请求登录认证 CAS会话(sessionCAS)鉴权失败,需要登录 跳转登录 用户输入账号密码 认证成功,创建sessionCAS和authCode 返回sessionCASId,302登录回调地址+authCode 保存sessionCASId 请求登录回调地址+authCode 通过authCode换取accessToken 校验authCode,创建accessToken,并注册系统A 返回accessToken 创建sessionA 返回sessionAId,返回资源 保存sessionAId 客户端 系统A CAS

实现要点

  1. Session鉴权。这里涉及到多个系统共享登录状态,当用户退出时需要同步注销登录状态,即既要单点登录,也要单点退出。所以子系统A和CAS系统都使用Session鉴权而不是Token鉴权。

  2. authCode换取accessToken。CAS登录认证之后重定向返回authCode,子系统A再通过后台接口的方式换取accessToken。跟用户数据相关的交互都是在后台完成的,避免数据泄漏。

  3. 注册服务。系统A拿authCode请求CAS换取accessToken并注册服务,后续用户注销登录时,CAS会通知系统A。

2.用户授权登录(OAuth)

用户授权第三方应用访问用户信息,无需提供账号密码即可完成登录。
例如微信用户授权登录第三方应用。

image.png

App扫码登录

本质上也是用户授权登录。通过扫码的方式,方便用户在移动端设备授权登录。

用户 第三方应用 微信平台 请求登录 获取登录二维码 展示登录二维码 扫码授权 登录结果 用户 第三方应用 微信平台

小结

单点登录是通过建立一个公共的认证中心(CAS),实现多个子系统间共享登录状态。这样用户只需登录一次,就可以访问其它互相信任的应用。用户授权登录是通过用户授权第三方应用访问用户信息,无需提供账号密码即可登录。

参考资料

前端登录,这一篇就够了

一文教你彻底搞定前后端所有鉴权方案,让你不再迷惘

二维码扫码登录是什么原理

史上最全的整合第三方登录的开源库

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值