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

单点登录

单点登录(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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

openGauss学习笔记-266 openGauss性能调优-TPCC性能调优测试指导-文件系统配置

文章目录 openGauss学习笔记-266 openGauss性能调优-TPCC性能调优测试指导-文件系统配置266.1 查看当前数据盘的文件系统类型266.2 对于需要修改的磁盘&#xff0c;备份所需的数据至其他磁盘或其他服务器266.3 格式化磁盘为xfs文件系统266.4 执行**步骤一** openGauss学习笔记-…

【Keil MDK5新建工程】STM32F103C8T6

一、参数及片上外设 二、系统结构及引脚定义 三、工程架构及新建工程步骤 四、GPIO模式 一、参数及片上外设 二、系统结构及引脚定义 三、工程架构及新建工程步骤 建立工程文件夹&#xff0c;Keil中新建工程&#xff0c;选择型号 工程文件夹里建立Core、Library、User等文件夹…

2024年华中杯数学建模竞赛ABC题思路分析

简单分析一下各个题目可能需要用到的方法和模型&#xff0c;完整代码和成品论文见文末 A题 太阳能路灯光伏板的朝向设计问题: 1. 球面几何、天文学相关知识,如赤纬角、太阳高度角、时角等概念和公式 2. 太阳辐射模型,根据太阳能辐射强度、大气衰减系数等计算地表太阳辐射强度…

绝对隔离+底层限制,成就猎鹰蜜罐“牢不可破”的立体化安全

前言 自网络诞生以来&#xff0c;攻击威胁事件层出不穷&#xff0c;网络攻防对抗已成为信息时代背景下的无硝烟战争。然而&#xff0c;传统的网络防御技术如防火墙、入侵检测技术等都是一种敌暗我明的被动防御&#xff0c;难以有效应对攻击者随时随地发起的无处不在的攻击和威胁…

【学习笔记】Vue3源码解析:第五部分 - 实现渲染(1)

课程地址&#xff1a;【已完结】全网最详细Vue3源码解析&#xff01;&#xff08;一行行带你手写Vue3源码&#xff09; 第五部分-&#xff1a;&#xff08;对应课程的第29-32节&#xff09; 第29节&#xff1a;《实现渲染的createRender方法》 1、通过createApp()方法得到一个…

AI热潮下,公链基础设施赛道都有哪些变化?

最近在一级市场&#xff0c;最火热的赛道无疑是AI&#xff0c;其次是BTC&#xff0c;每天聊的项目80%都集中在这两个赛道&#xff0c;我个人最多的时候一天可以聊5&#xff0c;6个AI项目。 可以预见的是AI泡沫会在明后年达到顶峰&#xff0c;随着数以百计的AI新项目上线&#…

QT实现客户端断开连接

Widget.cpp #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), socket(new QTcpSocket(this)) {ui->setupUi(this);//初始化界面ui->msgEdit->setEnabled(false); //不可用ui-…

SQL Server Management Studio 显示行号

前言 在使用 SQL Server Management Studio (SSMS) 进行数据库管理和查询时&#xff0c;能够看到代码的行号是非常有用的。这可以帮助您更容易地定位代码错误、讨论特定的代码行&#xff0c;或者在执行长查询时快速找到特定行。在本文中&#xff0c;我将向您展示如何在 SSMS 中…

AIDE:自动驾驶目标检测的自动数据引擎

AIDE&#xff1a;自动驾驶目标检测的自动数据引擎 摘要IntroductionRelated WorksMethodData FeederModel Updater4 Experiments 摘要 自动驾驶车辆&#xff08;AV&#xff09;系统依赖于健壮的感知模型作为安全保证的基石。然而&#xff0c;道路上遇到的物体表现出长尾分布&a…

图像生成模型浅析(Stable Diffusion、DALL-E、Imagen)

目录 前言1. 速览图像生成模型1.1 VAE1.2 Flow-based Model1.3 Diffusion Model1.4 GAN1.5 对比速览 2. Diffusion Model3. Stable Diffusion3.1 Text Encoder3.2 Decoder3.3 Generation Model 总结参考 前言 简单学习下图像生成模型的相关知识&#x1f917; 以下内容来自于李宏…

vue3+elment复杂详情页面打开后,再打开其他页面都显示空白,控制台也没什么特殊报错

页面使用了el-tabs 、 el-tab-pane、el-table 等标签 但是经测试不是这些问题导致的 js也使用了onMounted &#xff0c;但是除掉也时空白页面 反正之前人写的页面可乱&#xff0c;尤其是js这块&#xff0c;穿插引用import一大堆 主题页面样式布局如下 最后看到页面代码太乱…

古籍数字化平台:精校功能介绍

一、平台介绍 古籍数字化平台&#xff0c;本着公益性、低成本、合作共赢的三大原则&#xff0c;功能涵盖古籍OCR识别、族谱县志OCR识别、民国报纸OCR识别、图文逐字校对、数据著录、智能标点分段、精编排版、智能白话译文等&#xff0c;是一站式线上整理全流程平台。 平台集成…

备战面试K8S

备战面试&&K8S Kubernetes关于DockerDocker的优缺点分析 WebAssemblyWebAssembly与Container比较 CtrCrictlCtr和CriCtl的区别 Pod生命周期PodConditions容器状态Pod容器组成生命周期的流程 Kubelet EFK日志采集工具的优缺点 Kubernetes 容器运行接口 Container Runti…

2024年免费云服务器推荐,小编亲测好用!

随着云计算技术的飞速发展&#xff0c;云服务器以其弹性、高效、安全的特性&#xff0c;成为众多企业和个人用户的首选。尽管市面上有众多收费的云服务器产品&#xff0c;但免费的云服务器仍然吸引着大量用户&#xff0c;尤其是初学者和预算有限的用户。下面&#xff0c;我们就…

从API到Agent:洞悉LangChain工程化设计

作者&#xff1a;范志东 原文&#xff1a;https://mp.weixin.qq.com/s/zGS9N92R6dsc9Jk57pmYSg 本文作者试着从工程角度去理解LangChain的设计和使用。大家可以将此文档作为LangChain的“10分钟快速上手”手册&#xff0c;希望帮助需要的同学实现AI工程的Bootstrap。 我想做一…

[Vision Board创客营]学习片上Flash移植FAL

文章目录 [Vision Board创客营]学习片上Flash移植FAL介绍环境搭建使用组件测试porbeerasewriteread 结语 [Vision Board创客营]学习片上Flash移植FAL 水平较菜&#xff0c;大佬轻喷。&#x1f630;&#x1f630;&#x1f630; 介绍 &#x1f680;&#x1f680;Vision-Board 开…

安全开发实战(3)--存活探测与端口扫描

目录 安全开发专栏 前言 存活探测 端口扫描 方式一: 1.3.1 One 1.3.2 Two 1.3.3 批量监测 方式二: 1.3.1 One 1.3.2 Two 1.3.3 Three 1.3.4 扫描ip地址,提取出开放端口和协议 ​编辑 1.3.5 批量扫描(最终完成版) 总结 安全开发专栏 安全开发实战​http://t.csd…

MySql数据库从0-1学习-第五天事务和索引

事务 事务 是一组操作的集合&#xff0c;它是一个不可分割的工作单位。事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作 要么同时成功&#xff0c;要么同时失败。 注意事项,默认事务是自动提交的,也就是说,当执行一条DML语句,MySql会立即隐…

【Java开发指南 | 第八篇】Java变量、构造方法、创建对象

读者可订阅专栏&#xff1a;Java开发指南 |【CSDN秋说】 文章目录 Java变量构造方法创建对象 Java变量 在Java中&#xff0c;变量用于存储数据值。它们是程序中用于保存信息的一种基本方式。变量在程序执行过程中可以被赋予不同的值&#xff0c;并且这些值可以在程序的不同部分…

超越现实的展览体验,VR全景展厅重新定义艺术与产品展示

随着数字化时代的到来&#xff0c;VR全景展厅成为了企业和创作者展示作品与产品的新兴选择。通过结合先进的虚拟现实技术&#xff0c;VR全景展厅不仅能够提供身临其境的观展体验&#xff0c;而且还拓展了传统展示方式的界限。 一、虚拟现实技术的融合之美 1、高度沉浸的观展体验…