【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0

这篇具有很好参考价值的文章主要介绍了【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Vue-element-admin 是一个基于 Vue.js 和 Element UI 的后台管理系统框架,提供了丰富的组件和功能,可以帮助开发者快速搭建现代化的后台管理系统。

一、基本知识

(一)Vue-element-admin 的主要文件和目录

vue-element-admin/
  |-- build/                          # 构建相关配置文件
  |    |-- build.js                   # 生产环境构建脚本
  |    |-- check-versions.js          # 检查 Node.js 和 npm 版本的脚本
  |    |-- logo.png                   # 构建 Logo
  |    |-- utils.js                   # 构建工具函数
  |    |-- vue-loader.conf.js         # Vue loader 配置
  |    |-- webpack.base.conf.js       # webpack 基础配置
  |    |-- webpack.dev.conf.js        # webpack 开发环境配置
  |    |-- webpack.prod.conf.js       # webpack 生产环境配置
  |
  |-- config/                         # 项目配置
  |    |-- dev.env.js                 # 开发环境变量配置
  |    |-- index.js                   # 项目配置文件
  |    |-- prod.env.js                # 生产环境变量配置
  |
  |-- src/                            # 源代码
  |    |-- api/                       # 接口请求相关
  |    |-- assets/                    # 静态资源
  |    |-- components/                # 全局公用组件
  |    |-- directive/                 # 自定义指令
  |    |-- icons/                     # 图标
  |    |-- layout/                    # 全局布局
  |    |-- router/                    # 路由配置
  |    |-- store/                     # 全局状态管理
  |    |-- styles/                    # 全局样式
  |    |-- utils/                     # 工具函数
  |    |-- views/                     # 页面组件
  |    |-- App.vue                    # 入口页面
  |    |-- main.js                    # 入口 JS 文件

  |    |-- permission.js           # 路由守卫 文件
  |
  |-- static/                         # 静态资源
  |
  |-- .babelrc                        # Babel 配置
  |-- .editorconfig                   # 编辑器配置
  |-- .eslintignore                   # ESLint 忽略文件配置
  |-- .eslintrc.js                    # ESLint 配置
  |-- .gitignore                      # Git 忽略文件配置
  |-- index.html                      # 入口 HTML 文件
  |-- package.json                    # 项目信息和依赖配置
  |-- README.md                       # 项目说明文档
  |-- vue.config.js                   # Vue CLI 配置 

(二)单点登录系统涉及的文件和概念

  1. 客户端ID和客户端密钥:前端应用和后端应用在与单点登录系统通信时,需要提供客户端ID和客户端密钥进行身份验证。
  2. 授权码(authorization code):单点登录系统验证用户身份成功后生成的一次性授权码,用于换取访问令牌和刷新令牌。
  3. 访问令牌(access token):单点登录系统验证成功后返回给前端应用的令牌,用于后续请求时进行身份验证。
  4. 刷新令牌(refresh token):单点登录系统验证成功后返回给前端应用的令牌,用于在访问令牌过期时更新访问令牌。
  5. 前端应用使用的SDK或库文件:前端应用需要集成相应的SDK或库文件以便与单点登录系统进行通信。
  6. 单点登录系统的API文档:开发人员需要根据API文档了解单点登录系统提供的接口和参数,以便正确调用API接口。

二、 前端实现单点登录的基本流程

设计思路:为了避免code和access_token的泄露,所以大部分的和单点登录系统(统一认证)的交互都放到后端进行,前端尽可能的复用原来的代码,进行小的改动。整体思路如下:

1、登录页面--login.vue(修改原login.vue):用户访问前端应用,前端应用将用户重定向到后端登录接口。

<template>
  <div class="login-container">
    <div>正在重定向到登录页面...</div>
  </div>
</template>

<script>
export default {
  created() {
    const baseUrl = process.env.VUE_APP_BASE_API;
    //重定向到后端的SSOlogin/login接口
    window.location.href = `${baseUrl}/SSOlogin/login`;
  },
};
</script>

<style scoped>
.login-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  text-align: center;
}
</style>

2、 响应页面--callback.vue(新建):检查后端返回的URL+token访问链接中是否存在后端返回的token,如果存在则调用登录函数user/login进行前端的登录操作(调用login函数进行前端的登录,目的是将token持久化和存储到VUEX中,尽可能少的改动原来的代码。),并根据登录结果进行不同的处理。如果没有获取到token,则输出错误信息并终止后续逻辑。

<template>
  <div>
    <h1>Loading...</h1>
  </div>
</template>

<script>
export default {
  name: "Callback",
  data() {
    return {
    };
  },
  created() {
    // 获取 URL 查询参数中的授权码
    const token = this.$route.query.token;
    // 利用后端传递的token,调用login函数进行前端的登录,目的是将token持久化和存储到VUEX中,尽可能少的改动原来的代码
    if (token) {
      this.loading = true;
      this.$store.dispatch("user/login",token)
        .then(() => {
          // 登录成功,路由跳转
          this.$router.push({ path: this.redirect || "/" });
          this.loading = false;
        })
        .catch(() => {
          this.loading = false;
        });
    } else {
      console.log("error submit!!");
      return false;
    }
  },
};
</script>

【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0,【springboot+vue项目】,spring boot,vue.js,后端 对应的store/user.js。

3、 数据仓库 store/user.js,修改一下原来的Login函数即可。

原Login函数为:

//这里在处理登录业务
  async login({ commit }, userInfo) {
    //解构出用户名与密码
    const { username, password } = userInfo;
    let result = await login({ username: username.trim(), password: password });
    if(result.code==200){
      //vuex存储token
      commit('SET_TOKEN',result.data.token);
      //本地持久化存储token
      setToken(result.data.token);
      return 'ok';
    }else{
      return Promise.reject(new Error('faile'));
    }
  },

 修改后的Login为:

 // 登录 action
  async login({ commit }, token) {
    try {
      // 设置 token 持久化
      commit('SET_TOKEN', token);
      // 将 token 值保存在浏览器的本地存储中
      setToken(token);
      // 可以根据需要返回其他数据或状态
      return "ok";
    } catch (error) {
      // 异常时返回一个被拒绝的 Promise 对象
      return Promise.reject(error);
    }
  },

 所以,修改login函数,去掉了使用用户名和密码发送请求到后端接口验证登录,完整的代码如下:

// 引入需要使用的函数和模块
import { getInfo, logout  } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'

// 定义获取默认状态的函数
const getDefaultState = () => {
  return {
    token: getToken(), // 使用 getToken 函数获取 token 值
    name: '',
    avatar: ''
  }
}

// 定义 Vuex 模块的状态
const state = getDefaultState()

// 定义 Vuex 模块的变更操作
const mutations = {
  // 重置状态为默认状态
  RESET_STATE: (state) => {
    Object.assign(state, getDefaultState())
  },
  // 设置 token
  SET_TOKEN: (state, token) => {
    state.token = token
  },
  // 设置用户名
  SET_NAME: (state, name) => {
    state.name = name
  },
  // 设置用户头像
  SET_AVATAR: (state, avatar) => {
    state.avatar = avatar
  }
}

// 定义 Vuex 模块的异步操作
const actions = {
  // 用户登录
  // 登录 action
  async login({ commit }, token) {
    try {
      // 设置 token
      commit('SET_TOKEN', token);
      // 将 token 值保存在浏览器的本地存储中
      setToken(token);
      // 可以根据需要返回其他数据或状态
      return "ok";
    } catch (error) {
      // 异常时返回一个被拒绝的 Promise 对象
      return Promise.reject(error);
    }
  },
  async getInfo({ commit, state }) {
    try {
      // 发送请求获取用户信息
      const response = await getInfo(state.token)
      // 如果响应数据不存在,说明验证失败
      if (!response.data) {
        throw new Error('验证失败,请重新登录。')
      }
      // 获取用户名和头像
      const { name, avatar } = response.data
      // 设置用户名
      commit('SET_NAME', name)
      // 设置用户头像
      commit('SET_AVATAR', avatar)
      // 返回完整的响应对象
      return response
    } catch (error) {
      return Promise.reject(error)
    }
  },
  // 用户注销
  async logout({ commit, state }) {
    try {
      // 发送请求注销用户登录状态
      await logout(state.token)
      // 从本地存储中删除 token
      removeToken()
      // 重置路由
      resetRouter()
      // 重置状态
      commit('RESET_STATE')
    } catch (error) {
      return Promise.reject(error)
    }
  },
  // 重置 token 值
  async resetToken({ commit }) {
    try {
      // 从本地存储中删除 token
      removeToken()
      // 重置状态
      commit('RESET_STATE')
    } catch (error) {
      return Promise.reject(error)
    }
  }
}

// 导出 Vuex 模块
export default {
  namespaced: true, // 开启命名空间
  state,
  mutations,
  actions
}

4、  数据仓库store/user.js引入的函数和模块

 为了更清晰的了解整个过程,将上面store/user.js引入的函数和模块也贴在下面即:

【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0,【springboot+vue项目】,spring boot,vue.js,后端

因为 store/user.js中不用再向后端发请求,所以api/user.js中就可以把login删掉了。

api/user.js 

//api/user.js
import request from '@/api/request/request'

export function getInfo(token) {
  return request({
    url: '/user/getInfo',
    method: 'get',
    params: { token }
  })
}

export function logout() {
  return request({
    url: '/user/logout',
    method: 'post'
  })
}

utils/auth.js:用于处理用户身份验证 token 的工具函数,主要涉及对浏览器 Cookie 的操作。getToken:获取用户的身份验证 token,setToken:设置用户的身份验证 token,removeToken:移除用户的身份验证 token。

//utils/auth.js
import Cookies from 'js-cookie'

const TokenKey = 'vue_admin_template_token'

export function getToken() {
  return Cookies.get(TokenKey)
}

export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

export function removeToken() {
  return Cookies.remove(TokenKey)
}

5、路由守卫--permission.js:修改原来的)在每次路由导航之前进行身份验证和权限控制,确保用户在正确的身份状态下访问页面,并在页面切换后完成进度条的展示。

        如果用户已登录且获取了用户信息,则直接跳转到目标页面;

        如果用户未登录或获取用户信息失败,则跳转至登录页。

        同时,白名单内的页面可以在未登录状态下直接访问。

修改:配置白名单,把callback加进去

【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0,【springboot+vue项目】,spring boot,vue.js,后端

注意:通过 user/getInfo 获取用户信息  await  store.dispatch('user/getInfo'),所以api/user.js 里面要有getInfo函数。

 permission.js 完整的代码如下:

import router from './router'
import store from './store'
import { Message } from 'element-ui'
import NProgress from 'nprogress' // 引入进度条库
import 'nprogress/nprogress.css' // 引入进度条样式
import { getToken } from '@/utils/auth' // 引入获取 token 的方法
import getPageTitle from '@/utils/get-page-title' // 引入获取页面标题的方法

NProgress.configure({ showSpinner: false }) // 配置进度条

const whiteList = ['/login','/callback'] // 定义无需登录即可访问的白名单路由

router.beforeEach(async(to, from, next) => {
  NProgress.start() // 开始进度条

  document.title = getPageTitle(to.meta.title) // 设置页面标题

  const hasToken = getToken() // 获取 token

  if (hasToken) {
    if (to.path === '/login') {
      // 如果已登录却访问登录页,则重定向到首页
      next({ path: '/' })
      NProgress.done() // 完成进度条
    } else {
      const hasGetUserInfo = store.getters.name // 判断是否已获取用户信息
      if (hasGetUserInfo) {
        // 如果已获取,则直接进入路由
        next()
      } else {
        try {
          // 如果未获取,则通过 user/getInfo 获取用户信息
          await store.dispatch('user/getInfo')
          console.log("获取用户信息")
          next()
        } catch (error) {
          // 如果获取用户信息失败,则重置 token 并跳转至登录页
          await store.dispatch('user/resetToken')
          Message.error(error || 'Has Error')
          next(`/login?redirect=${to.path}`)
          // window.location.href = `www.baidu.com`;
          NProgress.done()
        }
      }
    }
  } else {
    if (whiteList.indexOf(to.path) !== -1) {
      // 如果在白名单中,则直接进入路由
      next()
    } else {
      // 否则跳转至登录页
      next(`/login?redirect=${to.path}`)
      
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done() // 完成进度条
})

6、请求拦截器中添加token到请求头:和原来一样)在请求拦截器中,从cookie中获取token,并将其添加到请求的头信息中,这样可以确保每次请求都带上了token。

import axios from 'axios'
import { MessageBox, Message } from 'element-ui'
import store from '@/store'
import { getToken } from '@/utils/auth'

// 创建一个axios实例
const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,  // 接口的基础路径
  timeout: 5000 // 请求超时时间
})

// 请求拦截器
service.interceptors.request.use(
  config => {
    // 在请求发送前做一些处理
    if (store.getters.token) {
      // 如果有token就在请求头中加上token
      config.headers['token'] = getToken()
    }
    return config
  },
  error => {
    // 对请求错误做些什么
    console.log(error)
    return Promise.reject(error)
  }
)

// 响应拦截器
service.interceptors.response.use(
  response => {
    // 对响应数据做一些处理,这里只返回响应数据中的data部分
    const res = response.data

    // 如果自定义的响应码不是20000,就判断为错误
    if (res.code !== 20000 && res.code !== 200) {
      // 在页面上显示错误信息
      Message({
        message: res.message || 'Error',
        type: 'error',
        duration: 5 * 1000
      })

      if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
        // 重新登录
        MessageBox.confirm('您已经登出,您可以取消以留在此页面,或重新登录', '确认登出', {
          confirmButtonText: '重新登录',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          store.dispatch('user/resetToken').then(() => {
            location.reload()
          })
        })
      }
      // 返回一个被拒绝的Promise对象,用来表示错误
      return Promise.reject(new Error(res.message || 'Error'))
    } else {
      // 如果没有错误,就返回响应数据中的data部分
      return res
    }
  },
  error => {
    // 对响应错误做些什么
    console.log('err' + error)
    Message({
      message: error.message,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(error)
  }
)

export default service

7、获取用户信息并渲染页面:在需要展示用户信息的地方,从cookie中获取用户信息,并将其渲染到页面上。

 文章来源地址https://www.toymoban.com/news/detail-828300.html

到了这里,关于【springboot+vue项目(十五)】基于Oauth2的SSO单点登录(二)vue-element-admin框架改造整合Oauth2.0的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Oauth2.0 单点登录 + 第三方授权认证】用户认证、授权模式

    本文主要对 SpringSecurity Oauth 2.0 用户认证,授权码授权模式、密码授权模式,以及授权流程进行讲解 开发中,有些功能只有管理员才有,普通用户是没有的。即需要对用户的身份进行认证,是管理员还是普通用户。认证方式有两种: 身份认证: 用户在访问相应资源时对用户

    2023年04月08日
    浏览(44)
  • oauth2.0第2季 分布式认证与授权实现单点登录

    1.使用jwttoken进行令牌传输,资源服务器在本地怎么验证token? 1.1.1 oauth是什么 1.1.2 oauth的角色 1.1.3 oauth的认证流程 1.1.4 oauth的4种模式 1.介绍单体架构  使用sesion保存会话信息的情况 2.前后端分离项目,调用方式 session架构不适合前后端分离项目 3.解决办法,引出oauth2.0 配置

    2024年02月11日
    浏览(32)
  • 深入探讨安全验证:OAuth2.0、Cookie与Session、JWT令牌、SSO与开放授权平台设计

    认证和授权是安全验证中的两个重要概念。认证是确认身份的过程,用于建立双方之间的信任关系。只有在认证成功的情况下,双方才可以进行后续的授权操作。授权则是在认证的基础上,确定用户或系统对资源的访问权限。 在设计一个权限认证框架时,可以考虑以下原则:

    2024年02月12日
    浏览(24)
  • SpringBoot 基于 OAuth2 统一身份认证流程详解

    了解OAUTH2统一认证基本概念 了解OAUTH2协议流程 了解OAUTH2各种模式类型 了解Spring Security OAuth设计 2. 分析 传统登陆认证介绍 单点登陆认证介绍 OAuth2简介 OAuth2角色 OAuth2协议流程介绍 OAuth2授权类型 OAuth2授权码模式流程 OAuth2简化模式 OAuth2密码模式 OAuth2客户端模式 Spring Security

    2024年02月15日
    浏览(41)
  • Spring Boot 中如何使用 Spring Security OAuth2 来实现单点登录

    在现代 Web 应用程序中,单点登录(Single Sign-On,简称 SSO)是一个非常重要的功能。Spring Security OAuth2 是 Spring Security 框架的一个扩展,它提供了一种简单的方式来实现 SSO。在本文中,我们将介绍如何在 Spring Boot 应用程序中使用 Spring Security OAuth2 来实现单点登录。 在开始之前

    2024年02月06日
    浏览(30)
  • Spring Security Oauth2.1 最新版 1.1.0 整合 (基于 springboot 3.1.0)gateway 完成授权认证

    目录 背景 demo地址 版本 Spring Boot 3.1 Spring Authorization Server 1.1.0 基础 spring security OAuth2 模块构成 授权方式 认证方式 集成过程 官方demo 代码集成 依赖 授权服务AuthorizationServerConfig配置 重要组件 测试 查看授权服务配置 访问授权服务 授权 回调 获取 access_token 获取用户信息 个性

    2024年02月11日
    浏览(37)
  • 深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)

    深入理解SSO原理,项目实践使用一个优秀开源单点登录项目(附源码)。 一、简介 单点登录(Single Sign On),简称为 SSO。 它的解释是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。 ❝ 所谓一次登录,处处登录。同样一处退出,处处退出。 ❞

    2024年02月11日
    浏览(29)
  • 单点登陆(SSO)基于CAS实现前后端分离的SSO系统开发「IDP发起」

    关于其他前端常见登录实现+单点登录方案,请见「前端常见登录实现方案 + 单点登录方案 」 单点登录(SSO),英文全称为 Single Sign On。 SSO 是指在多个应用系统中,用户只需要登录一次,就可以访问所有相互信任的应用系统。 一般同域的SSO,用共享session就可以实现了,常见

    2024年01月25日
    浏览(34)
  • 基于SAML 2.0对接阿里云的SSO(单点登录)

    公司使用的阿里云作为公有云,每次员工入职或离职时同时需要维护两套账号(一套内部账号,一套阿里云RAM账号),为了让用户能够使用内部账号能访问阿里云,所以决定对接阿里云的SSO 主流程介绍 用户访问阿里云 阿里云调转至公司内部的SSO(单点登录) 公司内部SSO让用户

    2023年04月10日
    浏览(32)
  • 基于SpringCloud + Oauth2.0 + ShiroRedis + JWT + Gateway + Nacos + Nginx + Vue实现的SaaS数字商城系统

    SaaS的英文全称是Software as a Service,意思是软件即服务 ,是云计算的其中一种服务模式 SaaS是一种通过Internet提供集中托管应用程序的方式,企业用户一般通过客户端或网页来使用,无需购买、安装或维护任何软件及硬件,因此 SaaS应用程序又被称为\\\"基于Web的软件\\\" 或 \\\"托管软件

    2024年01月20日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包