node 之 身份认证(cookie,session,token<jwt>)

对于服务端渲染和前后端分离这两种开发模式来说,分别有着不同的身份认证方案:

  .服务端渲染推荐使用 Session 认证机制 (SessIon也会用到cookie)

   前后端分离推荐使用 jwt  认证机制

 

cookie (保存在浏览器上)

    

 

简单案例

//导入模块
const express = require("express"); const path = require("path"); const cookieParser = require("cookie-parser");

//创建服务 const app = express(); app.listen("8001", () => { console.log("服务已开启"); }); // 应用级配置使用cookie-parser app.use(cookieParser()); //应用级配置 app.use(express.urlencoded({ extended: false })); //登录页面 app.get("/login.html", (req, res) => { res.sendFile(path.join(__dirname, "public", "login.html")); }); //登录提交的接口 app.post("/api/login", (req, res) => { if (req.body.username === "admin" && req.body.password === "123") { res.cookie("isLogin", 1, { maxAge: 2 * 1000 }); res.send(`<script>alert('登录成功');location.href="/index.html";</script>`); } else { res.send(`<script>alert('登录失败');location.href="/login.html";</script>`); } }); //后台首页 app.get("/index.html", (req, res) => { if (req.cookies && req.cookies.isLogin === "1") { res.sendFile(path.join(__dirname, "public", "index.html")); } else { res.send(`<script>alert('登录失败');location.href="/login.html";</script>`); } });

  

有效期

默认:浏览会话结束(也就是关闭浏览器)

设置有效期:res.cookie('isLogin',1,{maxAge:毫秒数})

 

优缺点:

  优点:

       体积小

       客户端存放,不占用服务器空间

       浏览器会自动携带,不需要写额外的代码,比较方便

   缺点

       客户端保存,安全性较低,但是可以存放加密的字符窜来解决

       可以实现跨域,但是难度大,难理解,代码难度高

      不适合前后端分离的开发

 

适用场景

      传统的服务器渲染模式

      存储安全性较低的数据,比如视频的存放位置等

 

session (保存在服务器上)

  

 

 

简单案例

//导入模块
const express = require("express"); const path = require("path"); // const cookieParser = require("cookie-parser"); const session = require("express-session"); const app = express(); app.listen("8001", () => { console.log("服务已开启"); }); // 应用级配置使用cookie-parser // app.use(cookieParser()); //应用级配置 app.use(express.urlencoded({ extended: false })); app.use( session({ secret: "123", //这个随便写,第二次进行加密 saveUninitialized: false, resave: false, }) ); //登录页面 app.get("/login.html", (req, res) => { res.sendFile(path.join(__dirname, "public", "login.html")); }); //登录提交的接口 app.post("/api/login", (req, res) => { console.log(req.body); if (req.body.username === "admin" && req.body.password === "123") { // res.cookie("isLogin", 1, { maxAge: 2 * 1000 }); req.session.isLogin = 1; res.send(`<script>alert('登录成功');location.href="/index.html";</script>`); } else { res.send(`<script>alert('登录失败');location.href="/login.html";</script>`); } }); //后台首页 app.get("/index.html", (req, res) => { if (req.session && req.session.isLogin === 1) { console.log("这个session是有数据的"); } // if (req.cookies && req.cookies.isLogin === "1") { // res.sendFile(path.join(__dirname, "public", "index.html")); // } else { // res.send(`<script>alert('登录失败');location.href="/login.html";</script>`); // } });

  

有效期

默认:浏览会话结束(也就是关闭浏览器)

 

优缺点:

  优点:

       服务端存放,安全性高

       浏览器会自动携带cookie,不需要写额外的代码,比较方便

       适合服务器端渲染模式

   缺点

       占用服务器端空间

       session实现离不开cookie,如果禁用cookie,session不好实现

      不适合前后端分离的开发

 

适用场景

      传统的服务器渲染模式

      安全性要求比较高的数据可以使用session存放,比如用户私密信息,验证码等

 

JWT(token)  json web token

注意:数据持久化 : localStorage 可以存储 token 

 

 

原理分析

  1.前端提交用户名和密码,服务端验证

  2.服务端验证通过,生成token,返回给前端

  3.前端自行保存token(localstorage)

  4.登录成功后,每次请求要在请求头带上Authorization,只是token

 

简单案例

//express-jwt 模块用于解密 'token' 字符串
//规范:解密token,
//1.unless:如果没有unless方法,则默认所有接口都需要验证,unless把不要验证的接口排除掉
//2.secret:加密秘钥
//3.algorithms:加密算法 ['HS256']
//4.path 取值范围,
//---字符串表示排除一个地址,如'/api/login'
//---数组:表示排除多个地址,如['/api/login','']
//---正则:表示排除符合规则的地址,如/^\/api/(排除以/api开头的接口)
//jsonwebtoken 模块用于加密 , 还可以控制哪些接口需要身份认证
//规范:
//1.token:'bearer '+jwt.sign(要保存的信息,秘钥,配置项)
//2.expiresIn 值是字符串时为毫秒,值是数字时为秒
//导入模块
const express = require("express");
const jwt = require("jsonwebtoken");
const expressJWT = require("express-jwt");

//创建服务
const app = express();
app.listen("8001", () => {
  console.log("服务已经开启");
});
//应用级配置
app.use(express.urlencoded({ extended: false }));

//用于token验证应用级配置
app.use(
  expressJWT({
    secret: "bigevent-970",
    algorithms: ["HS256"],
  }).unless({ path: /^\/api/ })
);

//请求
app.post("/api/login", (req, res) => {
  console.log(req.body);
  if (req.body.username === "admin" && req.body.password === "123") {
    res.json({
      status: 0,
      msg: "登录成功",
      token:
        "bearer " +
        jwt.sign({ username: "admin", age: 20 }, "bigevent-970", {
          expiresIn: 20,
        }),
    });
  } else {
    res.json({
      status: 1,
      msg: "登录失败",
    });
  }
});

//用去用户信息
app.get("/my/getUser", (req, res) => {
  res.json({
    status: 0,
    msg: "获取信息成功",
    data: {
      name: "admin",
      age: 18,
    },
  });
});

 

优缺点:

  优点:

       token由客户端保存,不会占用服务器空间

   缺点

       客户端发送请求的时候,需要手动编写代码,携带token

 

适用场景

      适合前后端分离的开发模式

 

 

 

   

posted @ 2021-03-01 23:39  zmztyas  阅读(270)  评论(0编辑  收藏  举报