Клиентское приложение OAuth2 с VueJS - Нужен компонент сервера? - PullRequest
0 голосов
/ 18 мая 2018

Я новичок в создании клиентских приложений JavaScript с OAuth2.

Я использую библиотеку JavaScript , которая использует localStorage для реализации OAuth, которая реализует Неявный поток, где требуется только идентификатор клиента - без client-secret .

Моя корпорация использует корпоративный провайдер идентификации / сервер авторизации (не социальные сети) для выдачи токенов.Мое пользовательское приложение проверяет токен при возврате, а затем продолжает навигацию, используя средства навигации Vue Router.

Вопрос: Является ли приведенный ниже код хорошей практической отправной точкой?Я планирую преобразовать это в одностраничное приложение JavaScript (Webpack), где приложение не будет загружать защищенные страницы, если токен не найден (только страница приветствия / посадки показана с кнопкой lOGIN для аутентификации).Нужна ли какая-то проверка сервера или достаточно ли клиентской библиотеки?

Вот простой пример моего потока аутентификации (использование Google в качестве сервера аутентификации для демонстрационных целей)

let client = new jso.JSO({
    providerID: "google",
    default_lifetime: 1800,
    client_id: '<my-app-id>',
    redirect_uri: "http://localhost/overview",
    authorization: "https://accounts.google.com/o/oauth2/auth",
    scopes: { request: ["https://www.googleapis.com/auth/userinfo.profile"] }
})

// check the browser response params when user returns        
client.callback()

const LandingPage = Vue.component('landing-page', {
    template: `<div>
        <h2>Thisis the landing page.</h2>
        <button v-on:click="oauthLogin">Login</button>
    </div>`,
    methods: {
        oauthLogin() {
            // get the token from the response params
            client.getToken()
        }
    }
})

const OverView = { template: '<div><h1>Welcome!</h1><p>Here is what site is about.</p></div>' }
const PResource = { template: '<h2>Protected Resource Content Here</h2>' }

const router = new VueRouter({
    mode: 'history',
    routes: [
        // {
        //     path: '*',
        //     component: NotFound
        // },
        {
            path: '/',
            component: LandingPage,
            meta: {
                requiresAuth: false
            }
        },
        {
            path: '/overview',
            component: OverView,
            meta: {
                requiresAuth: true
            }
        },
        {
            path: '/protected-resource',
            component: PResource,
            meta: {
                requiresAuth: true
            }
        }
    ]
})

router.beforeEach((to, from, next) => {
    const token = window.localStorage.getItem('tokens-google')

    if (to.matched.some(record => record.meta.requiresAuth)) {
        //if token exists, continue user to protected resource
        if (token !== null) {
            next()
        } else {
            //if no token exists, send to a landing page
            next({
                path: '/',
                query: {
                    redirect: to.fullPath
                }
            })
        }
    } else {
        // if token exists and user navigates to root, redirect to /overview
        if (token !== null && to.path == '/') {
            next({ path: '/overview' })
        } else {
            next() // make sure to always call next()!
        }
    }
})

var app = new Vue({
    el: '#app',
    computed: {
        checkToken() {
            return window.localStorage.getItem('tokens-google')
        }
    },
    router
})

Спасибо!

...