Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

常见的鉴权手段 #25

Open
zenglinan opened this issue Sep 22, 2019 · 0 comments
Open

常见的鉴权手段 #25

zenglinan opened this issue Sep 22, 2019 · 0 comments

Comments

@zenglinan
Copy link
Owner

一. session鉴权

原理:
1

前端如果注销的话就清除 cookie, 如果后端需要强制前端重新登陆认证的话就修改 session

session 鉴权的缺陷:

  1. 基于 cookie, 容易被劫持 (设置 http-only, 让 script 标签无法获取 cookie, 防止 XSS 攻击, 也可以用 https)
  2. 应用场景有限, 只有浏览器有 Cookie
  3. 如果是分布式部署,需要做多机共享 session 机制,实现方法: 可将 session 存储到数据库中或者 redis 中

session 鉴权的优点:

  1. 相比 JWT, 可以手动清除 session
  2. session 保存在服务端, 比较安全

二. JWT 鉴权 (jsonWebToken)

原理:

  1. 浏览器发起登录请求
  2. 请求通过后,服务器会向浏览器返回 token
  3. 前端接收到 token 后需要把 token 保存到本地 (比如 localStorage、sessionStorage) 用户点注销时前端删除保存的 token 即可
  4. 前端在每次请求时将 token 作为请求头中 Authorization 的值。至于为什么要用 Authorization 作为键名, 习惯习惯.....
  5. 服务器收到请求,去解析 token, 验证成功后会返回对应的用户数据

token

说了那么多, 那 token 到底是什么?
token 实际由三段字符串组成 Header.Payload.Signature, 中间用 . 作为分隔

  1. Header(一般是用 base64 编码的 json)
  • typ:token 的类型,这里固定为 JWT
  • alg:使用的 hash 算法,例如:HMAC SHA256 或者 RSA
  1. Payload(一般是用 base64 编码的 json)

    Payload 携带了要传递的主要信息
  2. Signature(加密的签名)

    前面两部分都是 base 64 编码的明文, 只有这部分是加密的签名。

说了这么多, 就我们来模拟一个 token 看看吧

这里我们启动一个 express 服务器, 引入 jsonwebtoken(可以帮助我们生成 token)

const express = require('express')
const JWT = require('jsonwebtoken')

const app = express()

app.get('/login', (req, res) => {
  const { username } = req.query
  const name = { username }
  const token = JWT.sign(name, 'abdddtasjfbwerkhjdczc') // 生成 token, 参数 1 为传递的主体信息, 参数 2 是一个随机字符串, 用来加密生成签名
  res.send(token)
})

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});

启动服务器并访问, 让我们看看浏览器端显示了什么?
1569132826(1)

仔细一看, 确实有两个 . 而且前面两段还是以 eyJ 开头的, 看起来像是 base64 编码的字符串。我们可以用 Buffer.from() 解析一下

第一段
1569133003(1)

第二段
1569133090(1)
这里面的 iatjsonwebtoken 帮我们添加的, 表示生成的时间 new Date().getTime()

第三段
这一段就解析不了了, 上面说过, 三段里只有这一段不是明文的, 是经过加密的签名。

JWT 鉴权的优点:

不基于 cookie, 可以跨端使用, 但是浏览器不会自动带上 token, 需要前端发送请求的时候带上

session 鉴权和 JWT 鉴权有个共同的好处就是: 都有加密的部分, 即使被劫取了, 也只能通过劫取的内容进行访问, 不能做到篡改。
如果要减少被劫持登录的风险, 可以 采用 HTTPS, 对传输过程进行一个 ssl 的加密, 其次, 当访问的 ip 改变时, 要求用户重新登录。

三. OAuth2 鉴权

OAuth2.0 实际上是第三方登录的一种鉴权协议

参考: https://www.barretlee.com/blog/2016/01/10/oauth2-introduce/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant