JS前端认证授权技巧有哪些

发布时间:2023-03-27 10:18:03 作者:iii
来源:亿速云 阅读:131

本篇内容介绍了“JS前端认证授权技巧有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

认证

认证 (Identification) 是验证当前用户的身份。

常见的认证技术:

授权

授权 (Authorization) 指赋予用户系统的访问权限。认证完用户身份后,系统会授予用户部分或者全部权限。系统要是没有权限控制需求的话,一般认证后用户就有全部权限。

实现授权的方式有:

鉴权

鉴权 (Authentication) 是指系统鉴定用户身份和权限。比如系统需要鉴定 session/cookie/token 的合法性和有效性。

认证、授权和鉴权关系

这三个概念的关系也是很清晰,就是一个前后依次发生的关系:认证 => 授权 => 鉴权。比如我们登录某个系统就完成了认证和授权,后续使用功能时就需要系统鉴权。

了解相关概念后,就可以开始介绍常见的认证授权方案。

认证授权方案

HTTP 基本认证

基本认证 (Basic 认证) 是 HTTP/1.0 就定义的认证方式,主要通过用户提供用户名和密码的方式,实现对用户身份的验证。

基本认证流程图

JS前端认证授权技巧有哪些

认证步骤解析

node 的简单实现

const express = require('express')
const app = express()
const protectedPath = '/protected_docs'
const realms = {
  [protectedPath]: {
    users: ['root'],
  },
}
app.get(protectedPath, (req, res, next) => {
  const realm = realms[req.path]
  const authorization = req.get('authorization')
  if (!authorization) {
    // 告知用户需要身份认证
    res.statusCode = 401
    res.set('WWW-Authenticate', 'Basic realm=' + encodeURIComponent(realm))
    res.end()
    return
  }
  const usernamePasswd = authorization.split(' ')[1] // Basic Y2h6aW5ncDoxMjM0NTY
  const [usrname, passwd] = Buffer.from(usernamePasswd, 'base64')
    .toString()
    .split(':')
  if (!realm.users.includes(usrname)) {
    // 用户不在realm里
    res.statusCode = 401
    res.set('WWW-Authenticate', 'Basic realm=' + encodeURIComponent(realm))
    res.end()
    return
  }
  const isValid = usrname === 'root' && passwd === '123456'
  if (!isValid) {
    // 用户账号、密码验证不通过
    res.statusCode = 403
    res.end()
    return
  }
  res.end(`welecom ${usrname}`)
})
app.listen(3000)

小结

优点:

缺点:

使用场景:

这边提一下,HTTP1.1 针对基本认证缺点,提供了摘要认证(Digest 认证),原理简单来说就是服务端会给浏览器一个 nonce 随机数,浏览器会将账号、密码和 nonce 等参数进行 md5 加密后传给服务端(同时传账号数据,密码不传),服务端获取到账号后,从数据库拿密码同样进行 md5 加密,加密后值和浏览器传的一样就认为认证成功。

摘要认证不再明文传输密码、可以防重放和避免报文被篡改,但是需要和 Https 配合使用。

Session-Cookie

Session-Cookie 认证是利用服务端的 Session(会话)和浏览器(客户端)的 Cookie 来实现的前后端通信认证模式。

什么是 Cookie

HTTP 是无状态协议,服务端在接收到客户端首次请求后,设置对应的 Cookie,随后浏览器在请求带上 Cookie,服务端就可以知道当前客户端状态。

Cookie 的特点:

什么是 Session

Session 的抽象概念是会话,是无状态协议通信过程中,为了实现中断/继续操作,将用户和服务器之间的交互进行的一种抽象。

Session 一般流程是:服务端接收到客户端首次请求后,设置一个 Session 来跟踪用户的会话,同时会给客户端一个 Session ID,后续客户端请求时在带上 Session ID,服务端即可找到对应的 Session,此时双方通信就是有状态的。

Session 特点:

Session-Cookie 流程

Session 流程中一般会设置 Session ID,通常 Session ID 会保存在 浏览器 Cookie 中,接下来看下整体流程。

JS前端认证授权技巧有哪些

认证步骤解析

简单代码示例

const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const port = 3000;
const session = require("express-session");
app.use(bodyParser());
app.use(
  session({
    key: 'SESSION_ID',
    secret: "your_secret_key",
    resave: false,
    saveUninitialized: false,
    cookie: { maxAge: 1000 * 60 * 60 * 8, signed: true },
  })
);
app.get("/", async function (req, res) {
  res.send(req.session);
});
app.get("/login", async function (req, res) {
  const authInfo = {
    id: '1',
    username: 'user',
  }
  const isValid = true
  if (isValid) {
    req.session.authInfo = authInfo
    res.send({
      success: true,
      info: "登录成功",
    });
  } else {
    res.send({
      success: false,
      info: "登录失败",
    });
  }
});
app.listen(port, () => {
  console.log(`node listening at http://localhost:${port}`);
});

使用 node 起好服务器后,先访问 /login,在访问首页 /, 可以看到首页输出用户名。同时打开 F12,在 Cookie 中可以看到 SESSION_ID 的数据。

小结

优点:

缺点:

使用场景:

Token

上述介绍中,我们知道了 Session-Cookie 的一些缺点,及 Session 的维护给服务端造成很大困扰,必须找地方存放它,又要考虑分布式的问题,所以 Token 方案就出来了。

什么是 Token

Token 是一个令牌,客户端访问服务器时,验证通过后服务端会为其签发一张令牌,之后,客户端就可以携带令牌访问服务器,服务端只需要验证令牌的有效性即可。

一般 Token 的组成:

uid(用户唯一的身份标识) + time(当前时间的时间戳) + sign(签名,Token 的前几位以哈希算法压缩成的一定长度的十六进制字符串)

Token 认证流程

JS前端认证授权技巧有哪些

认证步骤解析

Token的优缺点

优点:

缺点:

Refresh Token

业务接口用来鉴权的 Token,我们称之为 Access Token,为了安全性,Access Token 有效期一般设置的比较短。Access Token 过期后,需要用户重新登录,但是这种体验较差。

所以有了 Refresh Token, 可以用 Refresh Token 去获取 Access Token。

Refresh Token 的使用流程是在服务器校验 Token, 发现过期后,客户端可以使用 Refresh Token 发起请求,获取新的 Access Token 和 Refresh Token。

JSON Web Token(JWT)

上述 Token 中,一般只有 uid 信息,需要更多登录信息和其他数据的话,这时就需要查询数据库。每次都需要查询数据库,就会带来一些性能消耗。所以业界常用的 JWT 方案就出来了。

JWT 是 Auth0 提出的通过对 JSON 进行加密签名来实现授权验证的方案, 它的特点是自包含的,用户信息和认证是在一起的,无需像 Cookie-Session 一样需要 Session 服务器,或者像 Token 一样访问数据库获取用户信息。

JWT 本质上就是一组字串,通过(.)切分成三个为 Base64 编码的部分:

JWT 通常是这样的:xxxxx.yyyyy.zzzzz。

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJuYW1lIjoieGlhb21pbmciLCJkYXRhIjoiPT09PT09PT09PT09PSIsImlhdCI6MTY3OTgwNDA1NywiZXhwIjoxNjc5ODA0MTE3fQ
.FdJ6UD4Ff5zOz83f4hRDh2C86kN5f8aO_KeEtIwt3cM

JWT 认证流程

JS前端认证授权技巧有哪些

其实 JWT 的认证流程与 Token 的认证流程差不多,只是不需要再单独去查询数据库查找用户信息。

JWT 实例

const { expressjwt: jwt } = require('express-jwt')
const express = require('express')
const app = express()
const jsonwebtoken = require('jsonwebtoken')
const secretOrPrivateKey = 'hello' //加密token 校验token时要使用
app.use(
  jwt({
    secret: secretOrPrivateKey,
    algorithms: ['HS256'],
  }).unless({
    path: ['/getToken'], //除了这个地址,其他的URL都需要验证
  })
)
app.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    res.status(401).send('invalid token...')
  }
})
app.get('/getToken', function (req, res) {
  res.json({
    result: 'ok',
    token: jsonwebtoken.sign(
      {
        name: 'xiaoming',
        data: '=============',
      },
      secretOrPrivateKey,
      {
        expiresIn: 60 * 1,
      }
    ),
  })
})
app.get('/getData', function (req, res) {
  res.send('data')
})
app.listen(3000)

服务启动后,访问 /getToken 获取 JWT,然后在 Postman 中请求 /getData, Header 部分加上 Authorization: Bearer your jwt,比如 Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoieGlhb21pbmciLCJkYXRhIjoiPT09PT09PT09PT09PSIsImlhdCI6MTY3OTgwNjkyOCwiZXhwIjoxNjc5ODA2OTg4fQ.qFOT9IS_T1ZNsWWheRXP9MxYPh2l3SBGWLtp8ocnKAE

JWT 的优缺点

优点:

缺点:

使用场景:

Oauth 2.0

OAuth 这种方式登录相信大家都使用过,比如我们想登录某个网站时,通常会发现可以通过第三方的 QQ 或者微信登录,这个就是使用到了 OAuth。

OAuth 是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码提供给第三方网站。常见的提供 OAuth 认证服务的厂商:支付宝、QQ、微信、微博

OAuth 认证流程

JS前端认证授权技巧有哪些

认证步骤解析

使用 github 登录示例

准备工作:

1、创建 OAuth App

JS前端认证授权技巧有哪些

2、填写基本信息

JS前端认证授权技巧有哪些

3、获取 client_idclient_secret

JS前端认证授权技巧有哪些

代码示例

const express = require('express')
const app = express()
const querystring = require('querystring')
const axios = require('axios')
// GitHub登录参数配置;配置授权应用生成的Client ID和Client Secret
const config = {
  client_id: 'xxx',
  client_secret: 'xxxxxx'
}
// 登录接口
app.get('/github/login', function (req, res) {
  // 重定向到GitHub认证接口,并配置参数
  let path = 'https://github.com/login/oauth/authorize?client_id=' + config.client_id
  // 转发到授权服务器
  res.redirect(path)
})
// GitHub授权登录成功回调,地址必须与GitHub配置的回调地址一致
app.get('/passport/github/callback', async function (req, res) {
  console.log('callback...')
  // 服务器认证成功,回调带回认证状态code
  const code = req.query.code
  const params = {
    client_id: config.client_id,
    client_secret: config.client_secret,
    code: code
  }
  // 申请令牌token
  let tokenRes = await axios.post('https://github.com/login/oauth/access_token', params)
  const access_token = querystring.parse(tokenRes.data).access_token
  // 根据token获取用户信息
  userRes = await axios.get(`https://api.github.com/user`, {
    headers: {
      'Authorization': 'token ' + access_token
    }
  })
  // 渲染页面
  res.end(`
    <h2>Hello ${userRes.data.login}</h2>
    <img src="${userRes.data.avatar_url}" alt="">
  `)
})
app.listen(7001, () => {
  console.log('listening port at 7001...')
})

服务启动后,访问 /github/login,后续会跳转 github 登录授权,完成后即可看到你的 github 用户名和头像。

“JS前端认证授权技巧有哪些”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!

推荐阅读:
  1. 原生JS forEach()和map()遍历的异同点有哪些
  2. JS如何实现计算小于非负数n的素数的数量算法示例

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

js

上一篇:Swift中可选项Optional解包方式是怎么实现的

下一篇:怎么通过OSI七层模型打开计算机网络大门

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》