Single sign-on (sso)

PostMessage Api address

Iframe and postMessage are used

Main technical points used:

  • vue
  • koa
  • jwt
  • mongodb
  • iframe+postMessage

The general process for implementing single sign-on

  1. Create a sSOClient project that has only login functionality.
  2. Create an SSOServer project with the back-end project providing login interface authentication.
  3. Create a CompanyClient project and write only the front end for now.

Code implementation

1. Ssoclient project

We need to implement a login function, simple implementation is good, the main purpose of this lesson is to understand how to conduct single sign-on.

Encapsulating request API

Install axios yarn add AXIos NPM install axiosCopy the code

util/request.js

import axios from "axios";

const _axios = axios.create({
  baseURL: '/api'.timeout:10000
});

// Add request interceptor
_axios.interceptors.request.use((config) = > {
  // What to do before sending the request
  return config;
}, function (error) {
  // What to do about the request error
  return Promise.reject(error);
});

// Add a response interceptor
_axios.interceptors.response.use((response) = >{
  // What to do with the response data
  let data = response.data;
  console.log(response)
  if(response.status === 200) {return data;
  }
  return Promise.reject(data.msg);
}, function (error) {
  // Do something about the response error
  return Promise.reject(error);
});

export default _axios;
Copy the code

Globally mount the AXIos request, main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import axios from "./util/request";

Vue.config.productionTip = false
Vue.prototype.$axios = axios;

new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')
Copy the code

Login.vue

<template>
  <div>
    <input v-model="email" placeholder="Please enter email address"/>
    <input type="password" v-model="password" placeholder="Please enter your password"/>
    <button @click="toLogin">The login</button>
  </div>
</template>

<script>
export default {
  data(){
    return {
      email:'[email protected]'.password:'123456'.redirectUrl:' '}},created(){
    let search = window.location.search
    if(search == ' '| |! search.includes('? ')) {console.log('URL with no callback')}else {
      let str = window.location.search.split('? ') [1];
      console.log(str)
      this.redirectUrl = decodeURIComponent(str.split("=") [1]);
      console.log(this.redirectUrl)
    }
    
  },
  methods: {toLogin(){
      this.$axios({
        url:'/api/users/login'.method:'post'.data: {email:this.email,
          password:this.password
        }
      }).then(res= >{
        console.log(res)
        window.localStorage.setItem('token',res.token)
        if(this.redirectUrl){
          window.location.href = this.redirectUrl;
        } else {
          this.$router.push({name:'About'})
        }
      }).catch(res= >{})}}}</script>
Copy the code

vue.config.js

module.exports = {
  devServer: {
    open:true.port:'8000'.proxy: {
      '/api': {
          target: 'http://localhost:8888/'.// Address of the API server
          ws: true./ / agency web sockets
          changeOrigin: true.// Virtual sites need to change origin
          pathRewrite: {   // Rewrite paths such as '/ API /aaa/ CCC 'to '/aaa/ CCC'
              '^/api': ' '}}},}}Copy the code

We need to use KOA to build a server that can log in and do token authentication.

Create a VUE project companyClient that requires single sign-on

Add postMessage to sSOClient to send messages

This code can also be changed to vueRouter’s global guard.

export default {
  name: 'Home'.beforeCreate(){
    // FromCompany needs to use this field to determine whether to receive the message. The token was saved after we logged in earlier
    window.parent.postMessage({from:'sso.com'.token:localStorage.getItem('token')},The '*')}}Copy the code

companyclient

Create a new token.js file

util/token.js

This code could actually be written in the vueRouter global guard

window.addEventListener('message'.function(e){
  console.log('Iframe has received the message')
  if(e.data.from === 'sso.com') {if(e.data.token){
      console.log(e.data.token)
      localStorage.setItem('token',e.data.token);
    } else {
      let redirectUrl = window.location.href
      location.href=`http://localhost:8000/login? redirectUrl=${redirectUrl}`}}})let iframe = document.createElement('iframe');
iframe.width = 0;
iframe.height = 0;
iframe.style.display = 'none'
iframe.src = "http://localhost:8000"

document.body.appendChild(iframe);
Copy the code

Reference in main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './util/token'

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h= > h(App)
}).$mount('#app')
Copy the code