Я пытаюсь реализовать вход в Google в моем веб-приложении. Я использую Laravel пакет Socialite в бэкэнде. Проблема в том, что он работает в режиме SPA, но не работает в режиме SSR.
Поток моего входа в Google:
- Метод "googleLoginRedirect" вызывается на q- btn click.
- В ответ я получаю URL-адрес перенаправления Google от API, который я затем просто посещаю с помощью "window.location.href"
- Браузер переводит пользователя на страницу входа в Google.
- Пользователь входит в систему, используя учетные данные Google.
- Затем Google перенаправляет пользователя на URL-адрес обратного вызова. (URL-адрес обратного вызова состоит из уникального кода в параметрах, который может использоваться только один раз для получения сведений о пользователе)
- Используя метод "googleLoginCallback", я отправляю код из URL-адреса в качестве параметра бэкэнд-API, используя ax ios.
- В серверной части API социальной сети извлекает информацию о пользователе с помощью этого уникального кода и создает нового пользователя, если он еще не существует.
- Затем API возвращает токен.
- Установить маркер в поваре ie.
- Войти пользователя на панель управления.
Наблюдение:
- The вышеуказанный поток успешно работает при запуске приложения квазар в режиме SPA.
- На шаге 6 топор ios успешно отправляет код в API, НО во время работы в режиме SSR, API Socialite отвечает «400 Неверный запрос: этот код авторизации был использован. "
Я новичок в концепции SSR, поэтому я могу сказать, что это наивно, но запрос ax ios вызывается два раза? Как во второй раз с сервера узла? потому что уникальный код, отправленный Google, может быть использован только один раз. Пожалуйста, любые данные по этому вопросу ценны для меня.
// pages/login.vue
<template>
<q-btn @click="googleLoginRedirect" icon="lab la-google" />
</template>
<script>
export default {
methods: {
googleLoginRedirect () {
return new Promise((resolve, reject) => {
this.$axios.get('/api/login/google')
.then((response) => {
resolve(response)
if (response.data.url) {
window.location.href = response.data.url
}
})
.catch((error) => {
reject(error)
})
})
}
}
}
</script>
// pages/please-wait.vue
<template>
<p> Please wait while we are logging you with google </p>
</template>
<script>
export default {
methods: {
googleLoginCallback () {
return new Promise((resolve, reject) => {
this.$axios.get('/api/login/google/callback', { params: { code: this.$route.query.code } })
.then((response) => {
if (response.data.token) {
resolve(response)
this.$q.cookies.set('token', response.data.token)
this.$store.commit('user/setLoggedIn', true)
this.$router.push({ name: 'dashboard' })
this.$q.notify({ type: 'positive', message: 'Login Success' })
}
})
.catch((error) => {
reject(error)
this.$router.push({ name: 'login' })
this.$q.notify({ type: 'negative', message: 'Failed to login for some reason' })
})
})
}
},
created () {
this.googleLoginCallback()
}
}
</script>
Вот как выглядит мой загрузочный файл ios axe
// boot/axios.js
import Vue from 'vue'
import axios from 'axios'
import { Cookies } from 'quasar'
Vue.mixin({
beforeCreate () {
const options = this.$options
if (options.axios) {
this.$axios = options.axios
} else if (options.parent) {
this.$axios = options.parent.$axios
}
}
})
export default function ({ app, store, router, ssrContext }) {
const axiosInstance = axios.create({
baseURL: 'http://localhost:8000'
})
const cookies = process.env.SERVER
? Cookies.parseSSR(ssrContext)
: Cookies
axiosInstance.interceptors.request.use(function (config) {
const token = cookies.get('token')
if (token) {
config.headers.common.Authorization = `Bearer ${token}`
}
return config
}, function (error) {
return Promise.reject(error)
})
app.axios = axiosInstance
store.$axios = axiosInstance
router.$axios = axiosInstance
}