試着給VuePress添加登錄授權支持,基於v-dialogs


背景介紹

VuePress是個不錯的能基於Markdown快速構建靜態網站的框架,初步來說,對外訪問都是透明的。
但是可能因為一些保密需要,有些站點的文檔,我們希望控制一下訪問,所以我們借着別人的輪子記錄下怎么給VuePress實現簡單版本的全局登錄驗證彈窗。

給項目添加彈窗插件

npm i v-dialogs -D

新建Login.vueHelper.js

Login.vue

這是構建一個登錄框,基於v-dialogs插件的。

里面有一個簡單的表單判斷,代碼里面預埋了一些username和password,有符合的就放過了,你也可以換成你接口的邏輯。

# .vuepress\login\Login.vue

<template>
  <div class="login-form">
    <div class="form-header">賬號</div>
    <div>
      <input type="text" class="form-control" v-model="username">
    </div>
    <div class="form-header">密碼</div>
    <div>
      <input type="password" class="form-control" v-model="password">
    </div>

    <div class="btn-row">
      <button class="btn" @click="login">
        登錄
      </button>
    </div>
  </div>
</template>

<script>

import { STORAGE_KEY } from './helper'

export default {
  data () {
    return {
      username: '',
      password: ''
    }
  },
  methods: {
    login () 
    {
      if (this.username && this.password) 
      {
        var userAndWords = { 'user1': 'password1', 'user2' : 'password2'}
        var isMatchUser = false
        for(var key in userAndWords)
        {
           var tempUser = key;
           var tempPassword = userAndWords[key]
           if(this.username === tempUser && this.password === tempPassword)
           {
              isMatchUser = true
              break;
           }
        }

        if(isMatchUser)
        {
            const data = JSON.stringify({
              name: this.username,
              time: new Date().getTime()
            })
            window.localStorage.setItem(STORAGE_KEY, data)
            this.$emit('close', true)
        }
        else{
          this.$dlg.alert('抱歉,賬號密碼不對', {
          messageType: 'warning'
        })
        }
      } 
      else {
        this.$dlg.alert('請輸入賬號密碼', {
          messageType: 'warning'
        })
      }
    }
  }
}
</script>

<style lang="stylus">
.login-form
  padding: 1rem
  display flex
  flex-direction column
  box-sizing border-box
  .btn-row
    margin-top 1rem
  .btn
    padding 0.6rem 2rem
    outline none
    background-color #60C084
    color white
    border 0
  .form-header
    color #666
    margin-bottom 0.5rem
  .form-control
    padding 0.6rem
    border 2px solid #ddd
    width 100%
    margin-bottom 0.5rem
    box-sizing border-box
    outline none
    transition border 0.2s ease
    &:focus
      border 2px solid #aaa
</style>

賬號和密碼驗證通過之后,我們往STORAGE_KEY寫入了一個數據,以便后續刷新頁面檢查之前登錄結果,詳細判斷見下文。

helper.js

這是一個用來判斷是否登錄驗證通過的函數,如果返回true就算是驗證通過,返回false那就沒驗證通過了。

# .vuepress\login\helper.js

export const STORAGE_KEY = 'user_auth_xxxxxxxxxxxx'

// Do user authorization verify
export function checkAuth () 
{
  var auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
  return auth && Object.keys(auth).length
}

這個是判斷是否登錄過的函數,說直白點,就是上面的登錄成功后,會往這個key里面寫一個對象值,每次調用頁面之前,先走這個函數做一個檢查,如果拿出來的auth是你覺得合法的,你就true通過,不然就一直繼續彈登錄框了。

其實這里,我們也可以根據自己的需要,給拿到的auth對象進一步做判斷,當然要怎么搞就看你自己了。比如我會加一個過期時間,一個小時過期:

export function checkAuth () 
{
  var auth = JSON.parse(localStorage.getItem(STORAGE_KEY))
  console.log(auth)
  if(auth && auth.time){
    var preTime = new Date(auth.time)
    var nowTime = new Date().setHours(-1)
    if(nowTime > preTime)
    {
        return false;
    }
    return auth && Object.keys(auth).length
  }
  else
  {
    return false;
  }
}

嵌入新增的文件到VuePress

找到.vuepress下面的enhanceApp.js,如果沒有可以新建一個。

import { checkAuth } from './login/helper'
import Login from './login/Login'

export default ({
  Vue,
  options,
  router,
  siteData
}) => {
  Vue.mixin({
    // 請確保只在 beforeMount 或者 mounted 訪問瀏覽器 / DOM 的 API
    mounted() {
      const doCheck = () => {
        if (!checkAuth()) {
          this.$dlg.modal(Login, {
            width: 400,
            height: 350,
            title: '請登錄您的賬號',
            singletonKey: 'user-login',
            maxButton: false,
            closeButton: false,
            callback: data => {
              if (data === true) {
                // do some stuff after login
              }
            }
          })
        }
      }

      if (this.$dlg) {
        doCheck()
      } else {
        import('v-dialogs').then(resp => {
          Vue.use(resp.default)
          this.$nextTick(() => {
            doCheck()
          })
        })
      }
    }
  })
}

其中Vue.mixin是對全局混入插入,因為v-dialogs插件在注冊的過程中需要使用到document這個對象,所以這里一定要在beforeMount或者mounted時間來做。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM