Nodejs 第六十四章(SSO单点登录)

news2024/12/23 14:38:30

单点登录

单点登录(Single Sign-On,简称SSO)是一种身份认证和访问控制的机制,允许用户使用一组凭据(如用户名和密码)登录到多个应用程序或系统,而无需为每个应用程序单独提供凭据

SSO的主要优点包括:

  1. 用户友好性:用户只需登录一次,即可访问多个应用程序,提供了更好的用户体验和便利性。
  2. 提高安全性:通过集中的身份验证,可以减少密码泄露和密码管理问题。此外,SSO还可以与其他身份验证机制(如多因素身份验证)结合使用,提供更强的安全性。
  3. 简化管理:SSO可以减少管理员的工作量,因为他们不需要为每个应用程序单独管理用户凭据和权限。

举例说明

小满科技,小满教育,都是小满旗下的公司,那么我需要给每套系统做一套登录注册,人员管理吗,那太费劲了,于是使用SSO单点登录,只需要在任意一个应用登录过,其他应用便是免登录的一个效果,如果过期了,在重新登录

但是每个应用是不同的,登录用的是一套,这时候可以模仿一下微信小程序的生成一个AppId作为应用ID,并且还可以创建一个secret,因为每个应用的权限可以不一样,所以最后生成的token也不一样,还需要一个url,登录之后重定向到该应用的地址,正规做法需要有一个后台管理系统用来控制这些,注册应用,删除应用,这里节约时间就写死了。

image.png

代码编写

  1. 安装的依赖
  • express 启动服务编写接口
  • express-session 操作cookie
  • jsonwebtoken 生成token
  • cors 跨域
  1. 目录结构
  • vue A项目 用vite创建一个就好 npm init vite
  • react B项目 用vite创建一个就好 npm init vite
  • server/index.js nodejs端
  • sso.html 登录页面

server/index.js

const appToMapUrl = {
     //A应用id
    'Rs6s2aHi': {
        url: "http://localhost:5173", //对应的应用地址
        secretKey: '%Y&*VGHJKLsjkas', //对应的secretKey
        token:"" //token
    },
    //B应用id
    '9LQ8Y3mB': {
        url: "http://localhost:5174", //对应的应用地址
        secretKey: '%Y&*FRTYGUHJIOKL', //对应的secretKey
        token:"" //token
    },
}

完整版代码

server/index.js

import express from 'express'
import session from 'express-session'
import fs from 'node:fs'
import cors from 'cors'
import jwt from 'jsonwebtoken'

const appToMapUrl = {
    'Rs6s2aHi': {
        url: "http://localhost:5173",
        name:'vue',
        secretKey: '%Y&*VGHJKLsjkas',
        token: ""
    },
    '9LQ8Y3mB': {
        url: "http://localhost:5174",
        secretKey: '%Y&*FRTYGUHJIOKL',
        name:'react',
        token: ""
    },
}
const app = express()
app.use(cors())
app.use(express.json())
app.use(session({
    secret: "$%^&*()_+DFGHJKL",
    cookie: {
        maxAge: 1000 * 60 * 60 * 24 * 7, //过期时间
    }
}))
const genToken = (appId) => {
    return jwt.sign({ appId }, appToMapUrl[appId].secretKey)
}
app.get('/login', (req, res) => {
   //注意看逻辑 如果登陆过 就走if 没有登录过就走下面的
    if (req.session.username) {
    //登录过
        const appId = req.query.appId
        const url = appToMapUrl[appId].url
        let token;
        //登录过如果存过token就直接取 没有存过就生成一个 因为可能有多个引用A登录过读取Token   B没有登录过生成Token 存入映射表
        if (appToMapUrl[appId].token) {
            token = appToMapUrl[appId].token
        } else {
            token = genToken(appId)
            appToMapUrl[appId].token = token
        }
        res.redirect(url + '?token=' + token)
        return
    }
    //没有登录 返回一个登录页面html
    const html = fs.readFileSync(`../sso.html`, 'utf-8')
    //返回登录页面
    res.send(html)
})
//提供protectd get接口 重定向到目标地址
app.get('/protectd', (req, res) => {
    const { appId,username,password } = req.query //获取应用标识
    const url = appToMapUrl[appId].url //读取要跳转的地址
    const token = genToken(appId) //生成token
    req.session.username = username //存储用户名称 表示这个账号已经登录过了 下次无需登录
    appToMapUrl[appId].token = token //根据应用存入对应的token
    res.redirect(url + '?token=' + token) //定向到目标页面
})
//启动3000端口
app.listen(3000, () => {
    console.log('http://localhost:3000')
})

sso.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
<!--这里会调用protectd接口 并且会传入 账号 密码 和 appId appId会从地址栏读取-->
    <form action="/protectd" method="get">
        <label for="username">
            账号:<input name="username" id="username" type="text">
        </label>
        <label for="password">密码:<input name="password" id="password" type="password"></label>
        <label for="appId"><input name="appId" value="" id="appId" type="hidden"></label>
        <button type="submit" id="button">登录</button>
    </form>
    <script>
       //读取AppId
        const appId = location.search.split('=')[1]
        document.getElementById('appId').value = appId
    </script>
</body>

</html>

A 应用这里用Vue展示 App.vue

<template>
    <h1>vue3</h1>
</template>

<script setup lang='ts'>
//如果有token代表登录过了 如果没有跳转到 登录页面也就是SSO 那个页面,并且地址栏携带AppID
const token = location.search.split('=')[1]
if (!token) {
    fetch('http://localhost:3000/login?appId=Rs6s2aHi').then(res => {
        location.href = res.url
    })
}
</script>

<style></style>

B应用使用React演示 App.tsx

import { useState } from 'react'
function App() {
  const [count, setCount] = useState(0)
  //逻辑其实一样的只是区分了不用应用的AppId
  const token = location.search.split('=')[1]
  if (!token) {
      fetch('http://localhost:3000/login?appId=9LQ8Y3mB').then(res => {
          location.href = res.url
      })
  }
  return (
    <>
     <h1>react</h1>
    </>
  )
}
export default App

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1605957.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

EI、Scopus检索 | 2024年第四届机械、航空航天与汽车工程国际会议

会议简介 Brief Introduction 2024年第四届机械、航空航天与汽车工程国际会议&#xff08;CMAAE 2024&#xff09; 会议时间&#xff1a;2024年11月8 -10日 召开地点&#xff1a;中国北京 大会官网&#xff1a;www.cmaae.org 航空航天是当今世界最具挑战性和广泛带动性的高技术…

HCIP的学习(10)

OSPF不规则区域划分 区域划分 非骨干与骨干区域直接相连骨干区域唯一 限制规则&#xff1a; 非骨干区域之间不允许直接相互发布区域间路由信息OSPF区域水平分割&#xff1a;从非骨干区域收到的路由信息&#xff0c;ABR设备能接收到不能使用&#xff08;从某区域传出的路由&…

Tomcat漏洞利用工具-TomcatVuln

检测漏洞清单 CVE-2017-12615 PUT文件上传漏洞 tomcat-pass-getshell 弱认证部署war包 弱口令爆破 CVE-2020-1938 Tomcat 文件读取/包含项目地址 https://github.com/errors11/TomcatVuln TomcatVuln put文件上传 ajp协议漏洞 默认读取web.xml文件&#xff0c;漏洞利用…

使用yolov5训练自己的目标检测模型

使用yolov5训练自己的目标检测模型 使用yolov5训练自己的目标检测模型1. 项目的克隆2. 项目代码结构3. 环境的安装和依赖的安装4. 数据集和预训练权重的准备4.1利用labelimg标注数据和数据的准备4.1.1 **labelimg介绍:**4.1. 2 labelimg的安装 4.2 使用labelimg4.2.1 数据准备4…

【EI、CPCI稳定检索】2024年现代化教育、知识和信息管理国际学术会议(ICMEKIM 2024)

2024 International Conference on Modern Education, Knowledge and Information Management (ICMEKIM 2024) ●会议简介 2024年现代教育、知识与信息管理国际学术会议将聚焦于教育的最新趋势和信息管理技术的创新发展。本次会议将汇集全球教育专家、学者及行业领袖&#xf…

Vue2 基础学习-案例实践

数据管理信息的增删改查的实践 主要应用&#xff1a; 数据插值&#xff1a; {{xxx}}双向绑定&#xff1a;v-model点击事件函数&#xff1a;click列表xxx的增删改实现 xxx.push(row) 增加xxx.splice(id,1) 删除 一行{x,y} xxx[id]; 编辑 <!DOCTYPE html> <html la…

4月18日N皇后+解数独

51.N皇后 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案…

LangChain入门:18.使用ReAct 框架进行生成推理痕迹和任务特定行动来实现更大的协同作用

在这篇技术博文中&#xff0c;我们将深入探讨LangChain框架中的ReAct对话模型&#xff0c;以及如何利用它构建高效的智能对话系统。ReAct模型通过反应堆&#xff08;Reactor&#xff09;处理对话中的各种情况&#xff0c;实现了对复杂对话场景的有效解构。结合思维链&#xff0…

基于Java+Vue的校园交友系统(源码+文档+包运行)

一.系统概述 选题背景&#xff1a; 在大学校园中&#xff0c;学生们面临着新的环境和人际关系的挑战。有些学生可能感到孤独或者希望扩展自己的社交圈子&#xff0c;寻找志同道合的朋友或者潜在的伴侣。因此&#xff0c;设计一款校园交友平台具有重要意义。 研究意义&#xff1…

「51媒体」权重高新闻源央级媒体邀约资料有哪些?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 权重高的央级媒体邀约资源包括了中国一些最具影响力和权威性的新闻机构。具体如下&#xff1a; 人民日报&#xff1a;作为中国共产党中央委员会的机关报&#xff0c;人民日报具有极高的权…

Spring学习(三)——AOP

AOP是在不改原有代码的前提下对其进行增强 AOP(Aspect Oriented Programming)面向切面编程&#xff0c;在不惊动原始设计的基础上为其进行功能增强&#xff0c;前面咱们有技术就可以实现这样的功能即代理模式。Java设计模式——代理模式-CSDN博客 基础概念 连接点&#xff08…

SAM5716B 法国追梦DREAM 音频DSP芯片

法国追梦/DERAM SAM5504/5704/5716/5808音频DSP芯片,开发板&#xff0c;方案 可用于电子鼓、电子琴、电吉他、效果器、均衡器、啸叫抑制器等电声产品领域 全系列芯片&#xff1a; SAM2634 SAM2695 SAM5504B SAM5704B SAM5708B SAM5808B SAM5716B SAM5916B... 原厂开发…

【Qt】Qt Hello World 程序

文章目录 1、Qt Hello World 程序1.1 使用按钮实现1.1.1 使用可视化方式实现 1.1.2 纯代码方式实现 label创建堆&#xff08;内存泄漏&#xff09;或者栈问题Qt基础类&#xff08;Qstring、Qvector、Qlist&#xff09;乱码问题零散知识 1、Qt Hello World 程序 1.1 使用按钮实…

算法学习笔记:Bi-LSTM和Bi-GRU

这篇文章的作为前几篇RNN\LSTM\RNN的后续之作&#xff0c;主要就是补充一个这两个哥的变体&#xff0c;想详细了解RNN\LSTM\GRU的详细理论和公式推导以及代码的请前往下面链接&#xff1a; 算法学习笔记&#xff1a;循环神经网络&#xff08;Recurrent Neural Network)-CSDN博…

udemy视频教程下载:AI和ChatGPT提示工程精通指南

欢迎来到 ChatGPT 大师班&#xff01; 这个 ChatGPT 大师班&#xff1a;AI 和提示工程指南是您通往 AI 未来的全通道通行证。 以下是您的学习旅程&#xff1a; 理解和掌握 ChatGPT&#xff1a;您将深入了解 AI 和语言模型&#xff0c;重点是 ChatGPT。我们设计了这个部分&am…

前端三大件速成 01 HTML

文章目录 一、前端基础知识二、标签1、什么是标签2、标签的属性3、常用标签&#xff08;1&#xff09;声明&#xff08;2&#xff09;注释&#xff08;3&#xff09;html 根标签&#xff08;3&#xff09;head标签&#xff08;4&#xff09;body标签 三、特殊字符四、其他标签1…

java方法递归

简介 案例&#xff1a;阶乘 // 计算一个数的阶乘 public static int factorial(int n) {if (n 1) {return 1;}return n * factorial(n - 1); }案例 猴子吃桃子 // 猴子吃桃子问题 // 第一天吃了一半多一个 第十天剩一个 求第一天有多少个桃子 // 因为 f(x1) f(x)/2 - 1 // 所…

STL库 —— priority_queue 的编写

目录 一、 优先级队列的介绍 二、优先级队列的使用 2.1 建大堆 less 2.2 建小堆 greater 2.3 详解 greater 与 less 三、 priority_queue 的模拟实现 3.1 编写框架 3.2 编写简单函数 3.2 进堆 向上调整 3.3 出堆 向下调整 四、完整代码 一、 优先级队列的介绍 1.…

【Python系列】非异步方法调用异步方法

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

浅谈数据结构---红黑树、二叉树

红黑树简介 红黑树&#xff1a;在本质上还是二叉树&#xff0c;是一种高效的查找树。 特点 一边的数比另一边的数高太多时&#xff0c;自动旋转平衡 当数据量比较大时&#xff0c;层级比较多&#xff0c;查询效率低 如下图所示&#xff1a; 如果一边的数比另一边高太多时&…