web基础: SSO

144 阅读4分钟

登陆

token 定义:访问资源的凭据 携带方式:

// HTTP Header:
GET /drive/v2/files HTTP/1.1
Authorization: Bearer <token>
Host: www.googleapis.com/

// URL query string parameter
GET https://www.googleapis.com/drive/v2/files?token=<token>

SSO (Single sign-on)

公司内部会有一套公用的用户体系,用户只要登陆之后,就能够访问所有的系统。这就是单点登录(SSO: Single Sign-On) 区分定义: Authentication: 身份鉴别,以下简称认证,有权限访问系统,用于鉴别访问者是否是合法用户; Authorisation: 授权,用于决定你有访问哪些资源的权限 以下,把负责认证的服务称为 Authorization Server 或者 Identity Provider,以下简称 IdP;而负责提供资源(API调用)的服务称为 Resource Server 或者 Service Provider,以下简称 SP

SMAL 2.0 (比较老)

  • 还未登陆的用户打开浏览器访问你的网站(SP,以下都简称 SP),网站提供服务但是并不负责用户认证。 于是 SP 向 IdP 发送了一个 SAML 认证请求,同时 SP 将用户浏览器重定向到 IdP 。 IdP 在验证完来自 SAML 的请求无误之后,在浏览器中呈现登陆表单让用户进行填写用户名和密码进行登陆
  • 一旦用户登陆成功,IdP 会生成一个包含用户信息(用户名或者密码)的 SAML token (SAML token 又称为 SAML Assertion,本质上是 XML 节点),IdP 向 SP 返回 token, 并且将用户重定向到 SP (token 的返回是在重定向步骤中实现的,下面会详细说明) SP 对拿到的 token 进行验证,并从中解析出用户信息,例如他们是谁以及他们的权限有哪些。此时就能够根据这些信息允许用户访问我们网站的内容了

OAuth 2.0

用户通过客户端(可以是浏览器也可以是手机应用)想要访问 SP 上的资源,但是 SP 告诉用户需要进行认证,将用户重定向至 IdP IdP 向用户询问 SP 是否可以访问用户信息,如果用户同意,IdP 向客户端返回 access code 客户端拿 code 向 IdP 换 access token,并拿着 access token 向 SP 请求资源 SP 接受到请求之后拿着附带 token 向 IdP 验证用户的身份

OPEN ID vs AuthID OpenID 只用于身份认证(Authentication),允许你以同一个账户在多个网站登陆。它仅仅是为你的合法身份背书,当你以 Facebook 账号登陆某个站点之后,该站点无权访问你的在 Facebook 上的数据 OAuth 用于授权(Authorisation),允许被授权方访问授权方的用户数据

JWT

header header 用于描述元信息,例如产生 signature 的算法:

{
    "typ": "JWT",
    "alg": "HS256"
}

其中alg关键字就指定了使用哪一种哈希算法来创建 signature payload payload 用于携带你希望向服务端传递的信息。你既可以往里添加官方字段(这里的“字段” (field) 也可以被称作“声明” claims),例如iss(Issuer), sub(Subject), exp(Expiration time),也可以塞入自定义的字段,比如 userId:

{
    "userId": "b08f86af-35da-48f2-8fab-cef3904660bd"
}

signature signature 译为「签名」 创建签名要分以下几个步骤:

  • 你需要从接口服务端拿到密钥,假设为secret
  • 将header进行 base64 编码,假设结果为headerStr
  • 将payload进行 base64 编码,假设结果为payloadStr
  • 将headerStr和payloadStr用.字符串拼装起来成为字符data
  • 以data和secret作为参数,使用哈希算法计算出签名
// Header
{
  "typ": "JWT",
  "alg": "HS256"
}
// Payload:
{
  "userId": "b08f86af-35da-48f2-8fab-cef3904660bd"
}
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VySWQiOiJiMDhmODZhZi0zNWRhLTQ4ZjItOGZhYi1jZWYzOTA0NjYwYmQifQ.-xN_h82PHVTCMA9vdoHrcZxH-x5mb11y1537t3rGzcM

常见session工作原理

  • 用户在浏览器登陆之后,服务端为用户生成唯一的 session id,存储在服务端的存储服务(例如 MySql, Redis)中 该 session id 也同时返回给浏览器,以 SESSION_ID 为 KEY 存储在浏览器的 cookie 中
  • 如果用户再次访问该网站,cookie 里的 SESSION_ID 会随着请求一同发往服务端
  • 服务端通过判断 SESSION_ID 是否已经在 Redis 中判断用户是否处于登陆状态

理论上来说,JWT 机制可以取代 session 机制。用户不需要提前进行登陆,后端也不需要 Redis 记录用户的登陆信息。客户端的本地保存一份合法的 JWT, 当用户需要调用接口时,附带上该合法的 JWT,每一次调用接口,后端都使用请求中附带的 JWT 做一次合法性的验证。这样也间接达到了认证用户的目的。

公司SSO迭代

扫码登陆

参考:juejin.cn/post/684490…