2017-08-25 44 views
1

只需要高層概述如何構建此功能。 我有一個身份驗證js對象(es6類),實例化一次,並使用JWT。如何使用JWT處理Vuejs身份驗證的簡單高級概述

import { getRouteByName, getRouter } from 'appRouter' 
import axios from 'axios' 

let instance = null 
class AppAuthentication { 
    constructor (http, router, localStorage = window.localStorage) { 
    if (!instance) { 
     instance = this 
     this.storage = localStorage 
     this.http = http 
     // this.router = router // but it will be undefined 
     this.api = http.create({baseURL: someURL, headers: {'Authorization': 
     'Bearer ' + this.token}}) 
     this.watchRoutes() 
    } 
    return instance 
    } 

    watchRoutes() { 
    this.router.beforeEach((to, from, next) => { 
     let login = 'Login' 
     if (to.name !== login && this.isLoggedOut()) { 
     return next(getRouteByName(login)) 
    } 
    next() 
    }) 
    } 
    login (credentials) { 
    return this.http.post(`${SOME_URL}/login`, credentials) 
    } 

    finishAuthentication (token) { 
    this.setToken(token) 
    this.router.replace('/') 
    } 
    logout() {...} 
    set token (token) { ... } 
    get token() { ... } 
    get router:() => getRouter() // this sucks 
    isLoggedIn() {...} 
    isLoggedOut() {...} 
} 
export default new AppAuthentication(axios, router /*(here router will be undefined)*/) 

問題是,該對象是在Vue路由器「準備好」之前實例化的,因此引用未定義。我有一個蹩腳的getter可以回到vue路由器。顯然這不是最好的方法。

我看到在應用程序中包含內容的reactJS域中的高級組件。沒有看到這樣的事情是真的。什麼是高層次的做法呢?

像這樣的方式來做到這一點?

<app> 
    <authentication> 
    <some-tag></some-tag> 
    <router-view></router-view> 
    </authentication> 
</app> 

回答

0

我不確定我完全理解了您擁有的認證對象。我建議使用Vuex來維護用戶狀態,而不是將其存儲在本地存儲中。您的「獲取令牌」可以是一種行爲,您的「設置令牌」是一種突變。您可以使用Persisted State將Vuex鏡像到localStorage。

這裏是我是如何處理的JWT令牌:

1)要求令牌除了登錄所有呼叫路由。你在路由器的後衛中這樣做。因此,像這樣在routes.js如果使用本地存儲:

router.beforeEach((to, from, next) => { 
let now = new Date() 
if (/login|reset|activate|forgot/.test(to.path.toLowerCase())) { 
    next() 
} 
else if (localStorage.getItem('token') && localStorage.getItem('tokenExpires') > now){ 
    next() 
} 
else { 
    next('/login') 
} 

2)手柄403或其它驗證錯誤,所以他們的路線登陸或任何你想要它去。在我目前的應用程序中,我們使用GraphQuery和Fetch,所有請求都通過一個GraphQL.js文件,因此我們有一個簡單的邏輯處理請求處理位置。

3)在登錄組件本身處理api調用的日誌記錄,將響應發送到Vuex突變或將其存儲在本地/會話存儲中。

Vue的一大優點是其簡單性。提示:如果可以,將相關功能放在組件本身的其他地方,而不是重複使用。它更直觀,使代碼更易於維護。

+0

最後我做了一個auth對象,它把路由器和存儲作爲一個依賴關係。它處理與localstorage的接口,並且只在用戶登錄時才發佈給vuex一個布爾值。這與你所說的並不遙遠。這是一個廣泛的問題......所以你爲自己贏得了一個機會。 – Simon

+1

@Simon,謝謝。我會說,根據我的經驗,您希望將令牌保存到狀態而不是本地存儲。我做了一個並排的比較,它使用本地存儲要慢得多,我不得不像從API中拉出來一樣對待它。例如,我所從事的一個應用程序需要高安全性,並在每次請求時更改標記。從本地存儲中存儲並拉出它不起作用,因爲寫入和讀取的延遲時間足以使它有時無法獲得正確的標記,或者其他時間會回到空白。總的來說,我的經驗是Vue對於本地存儲「太快」了 –