sa-token + springcloud +vue 集成

SSO(Single Sign On)

单点登录(SingleSignOn,SSO),就是通过用户的一次性鉴别登录。当用户在身份认证服务器上登录一次以后,即可获得访问单点登录系统中其他关联系统和应用软件的权限,同时这种实现是不需要管理员对用户的登录状态或其他信息进行修改的,这意味着在多个应用系统中,用户只需一次登录就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的。
https://baike.baidu.com/item/SSO/3451380
解决方案

解决方案

这里只是简单简述下我自己验证过的方案

1.CAS

CAS是Central Authentication Service的缩写,中央认证服务,一种独立开放指令协议。CAS 是 耶鲁大学(Yale University)发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法,CAS 在 2004 年 12 月正式成为 JA-SIG 的一个项目。
待续

2. Spring Security 5.2 OAuth2 SSO

3. Sa-Token-SSO

Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证权限认证单点登录OAuth2.0分布式Session会话微服务网关鉴权 等一系列权限相关问题。
https://sa-token.dev33.cn/doc/index.html#/
在官方文档中,直接定位到sso模块二,然后扩展到三

集成到真实项目

因为真实项目的鉴权中心使用的是Spring Security OAuth2 集成的,然后sa-token只是做了登录,然后进行模拟登录,内部还是使用原项目的鉴权.

前端改造

完整的内容
https://flowus.cn/share/88f4fa31-cc48-4a15-b671-328e79532372
【FlowUs 息流】SSO 解决方案

api.js

import request from '@/router/axios';

export const isLogin = () => request({
  url: '/sa/isLogin',
  method: 'get',
  headers: {
    "X-Requested-With": "XMLHttpRequest",
    "satoken": localStorage.getItem("satoken")
  }
})

export const getSsoAuthUrl = (row) => request({
  url: '/sa/getSsoAuthUrl',
  method: 'post',
  params: {clientLoginUrl:row}
})

export const doLoginByTicket = (row) => request({
  url: '/sa/doLoginByTicket',
  method: 'post',
  params: {ticket:row}
})

export const getUserInfo = () => request({
  url: '/sa/sso/myinfo',
  method: 'get',
})

export const ssoLogout = () => request({
  url: '/sa/sso/logout',
  method: 'get',
  headers: {
    "X-Requested-With": "XMLHttpRequest",
    "satoken": localStorage.getItem("satoken")
  },
})

路由添加

{
    path: '/ssoLogin',
    name: 'ssoLogin',
    component: () =>
      import( /* webpackChunkName: "page" */ '@/page/sso/sso-login'),
    meta: {
      keepAlive: true,
      isTab: false,
      isAuth: false
    }
  },

login.vue改造
在登录页面进行改造.

 created() {
   //注释掉原有的方法,替换成验证sso的方法
    this.ssoInit();
    // this.getTenant();
    // this.refreshCode();
  },

在methods 方法体中添加

  ssoInit() {
      //检查是否已登录
      isLogin().then((res) => {
        if (!res.data.data) {
          this.$router.push({
            path: 'ssoLogin',
            query: {
              back: 'http://localhost:1888/#/ssoLogin'
            }
          });
        }
      })
    },

sso-login.vue

<template>
  <div>
  </div>
</template>

<script>
import {mapGetters} from "vuex";
import {doLoginByTicket, getSsoAuthUrl, getUserInfo} from "@/api/sso/sso";

export default {
  name: "sso-login",
  computed: {
    ...mapGetters(["website", "tagWel"])
  },
  created() {
    this.getTicket();
  },
  methods: {
    getTicket() {
      var back = this.getParam2('back');
      var ticket = this.getParam('ticket');
      if (ticket) {
        this.doLoginByTicket(ticket);
      } else {
        this.goSsoAuthUrl();
      }
    },
    goSsoAuthUrl() {
      getSsoAuthUrl(location.href).then((res) => {
        location.href = res.data.data;
      })
    },
    doLoginByTicket(ticket) {
      doLoginByTicket(ticket).then((res) => {
        localStorage.setItem('satoken', res.data);
        //调用user-info
        getUserInfo().then((res2) => {
          var data = res2.data;
          var loginForm = {tenantId: data.tenant_id,deptId:data.dept_id,roleId:data.role_id,username:data.user_name,password:'admin',key:'account'};
          //到这儿其实就已经登录结束了.下面的方法是进行模拟登录因为这个项目的鉴权中心是
          //Spring Security OAuth2 token不通用.参考原项目的登录页面就行,需要什么参数通过认证中心的userinfo接口返回即可.
          this.$store.dispatch("LoginByUsername", loginForm).then(() => {
            this.$router.push({path: this.tagWel.value});
            loading.close();
          }).catch(() => {
            loading.close();
            this.refreshCode();
          });
        })
      })
    },
    getParam(name, defaultValue) {
      var query = window.location.search.substring(1);
      var vars = query.split("&");
      for (var i = 0; i < vars.length; i++) {
        var pair = vars[i].split("=");
        if (pair[0] == name) {
          return pair[1];
        }
      }
      return (defaultValue == undefined ? null : defaultValue);
    },
    getParam2(name) {
      var query = window.location.href.split('?');
      var vars = query[1];
      var strings = vars.split('=');
      if (name == strings[0]) {
        return strings[1];
      } else {
        return null;
      }
    },
  }
}
</script>

<style scoped>

</style>

vue.config.js
添加代理,在devServer方法体重

 '/sa': {
        //本地服务接口地址
        target: 'http://localhost:9001',
        ws: true,
        pathRewrite: {
          '^/sa': '/'
        }
      },
登出

在store 中user.js中找到登出方法

// 登出
    LogOut({commit}) {
      return new Promise((resolve, reject) => {
        //原有方法的登录代码
        
        //添加
        ssoLogout().then(() => {
          //website.ssoLogin 为了避免在这里写死,所有替换到统一的js中
          //ssoLogin: 'http://localhost:1888/#/login'
          location.href = website.ssoLogin
        })
      })
    },

到这儿springcloud + vue 的项目就改造成功了.

还有一个springboot + vue admin element 改造案例
有待后续

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值