From 2e123607ecf38d5e1198c469e734f81820d8fc17 Mon Sep 17 00:00:00 2001 From: Devin Cowan Date: Thu, 16 Nov 2023 08:43:34 -0500 Subject: [PATCH] frontend use JWT instead of cookie --- app/frontend/src/_helpers/fetch-wrapper.js | 57 ++++++++++++++++++++++ app/frontend/src/auth.js | 43 ++++++++++------ app/frontend/src/constants.js | 8 +-- app/frontend/src/stores/auth.js | 14 +++--- 4 files changed, 97 insertions(+), 25 deletions(-) create mode 100644 app/frontend/src/_helpers/fetch-wrapper.js diff --git a/app/frontend/src/_helpers/fetch-wrapper.js b/app/frontend/src/_helpers/fetch-wrapper.js new file mode 100644 index 00000000..a5959fbc --- /dev/null +++ b/app/frontend/src/_helpers/fetch-wrapper.js @@ -0,0 +1,57 @@ +import { useAuthStore } from '@/stores/auth'; + +export const fetchWrapper = { + get: request('GET'), + post: request('POST'), + put: request('PUT'), + delete: request('DELETE') +}; + +function request(method) { + return (url, body) => { + const requestOptions = { + method, + headers: authHeader(url) + }; + if (body) { + requestOptions.headers['Content-Type'] = 'application/json'; + requestOptions.body = JSON.stringify(body); + } + console.log("url", url, "optoins", requestOptions) + return fetch(url, requestOptions).then(handleResponse); + } +} + +// helper functions + +function authHeader(url) { + // return auth header with jwt if user is logged in and request is to the api url + const { token } = useAuthStore(); + const isLoggedIn = !!token?.token; + const isApiUrl = url.startsWith(import.meta.env.VITE_APP_API_URL); + alert(`Isapi:${isApiUrl} isloggedin:${isLoggedIn}`) + if (isLoggedIn && isApiUrl) { + return { Authorization: `Bearer ${token.token}` }; + } else { + return {}; + } +} + +function handleResponse(response) { + return response.text().then(text => { + const data = text && JSON.parse(text); + + if (!response.ok) { + // const { user, logout } = useAuthStore(); + // if ([401, 403].includes(response.status) && user) { + // // auto logout if 401 Unauthorized or 403 Forbidden response returned from api + // logout(); + // } + + const error = (data && data.message) || response.statusText; + return Promise.reject(error); + } + + return data; + }); +} \ No newline at end of file diff --git a/app/frontend/src/auth.js b/app/frontend/src/auth.js index 7989c5f8..f7a532dd 100644 --- a/app/frontend/src/auth.js +++ b/app/frontend/src/auth.js @@ -1,19 +1,17 @@ -import { ENDPOINTS, APP_URL } from '@/constants' +import { ENDPOINTS, APP_URL, OAUTH2_REDIRECT_URL } from '@/constants' import { useAuthStore } from '@/stores/auth' -// import { Notifications } from '@cznethub/cznet-vue-core' +// import { fetchWrapper } from '@/_helpers/fetch-wrapper'; // function openLogInDialog(redirectTo) { // this.logInDialog$.next(redirectTo); // } export async function logIn(callback) { - const authStore = useAuthStore(); const response = await fetch(ENDPOINTS.authCuahsiAuthorize) const json = await response.json() // alter redirect uri const authUrl = new URL(json.authorization_url) - // const originalRedirect = authUrl.searchParams.get('redirect_uri') - authUrl.searchParams.set('redirect_uri', `${APP_URL}/#/auth-redirect`) + authUrl.searchParams.set('redirect_uri', OAUTH2_REDIRECT_URL) window.open( authUrl.toString(), '_blank', @@ -25,20 +23,35 @@ export async function logIn(callback) { } const params = event.data + const url = `${ENDPOINTS.authCuahsiCallback}${params}` - await fetch(url, {credentials: 'include', mode: 'cors'}) - - let userInfo = await fetch(`${ENDPOINTS.userInfo}`, { - method: 'GET', - credentials: 'include', - mode: 'cors' + const resp = await fetch(url) + const json = await resp.json() + const authStore = useAuthStore(); + authStore.login(json) + + // const userInfo = awaitw + const userinfo = await fetch(ENDPOINTS.userInfo, { + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${json.access_token}`, + } }) - if (userInfo.ok){ - userInfo = await userInfo.json() - authStore.login(userInfo) - event.source.close() + if (userinfo.ok){ + const result = await userinfo.json(); + authStore.user = result + console.log(result) + // await User.commit((state) => { + // state.isLoggedIn = true; + // state.accessToken = event.data.accessToken; + // }); + // this.loggedIn$.next(); + // this.isLoginListenerSet = false; callback?.() + }else{ + alert("error logging in") } + event.source.close() }) } diff --git a/app/frontend/src/constants.js b/app/frontend/src/constants.js index 5a85e923..985c451c 100644 --- a/app/frontend/src/constants.js +++ b/app/frontend/src/constants.js @@ -1,14 +1,14 @@ export const APP_NAME = import.meta.env.VITE_APP_NAME || ""; export const APP_URL = import.meta.env.VITE_APP_URL || ""; -export const CLIENT_ID = import.meta.env.OAUTH2_CLIENT_ID || ""; +export const APP_BASE = import.meta.env.VITE_APP_BASE || ""; +export const OAUTH2_REDIRECT_URL = import.meta.env.VITE_OAUTH2_REDIRECT_URL || ""; export const API_BASE = import.meta.env.VITE_APP_API_URL || ""; export const ENDPOINTS = { openapi: `${API_BASE}/openapi.json`, - authCuahsiAuthorize: `${API_BASE}/auth/cookie/authorize`, - authCuahsiCallback: `${API_BASE}/auth/cookie/callback`, + authCuahsiAuthorize: `${API_BASE}/auth/front/authorize`, + authCuahsiCallback: `${API_BASE}/auth/front/callback`, authenticatedRoute: `${API_BASE}/authenticated-route`, - logout: `${API_BASE}/auth/cookie/logout`, userInfo: `${API_BASE}/users/me`, submit: `${API_BASE}/submit`, download: `${API_BASE}/url`, diff --git a/app/frontend/src/stores/auth.js b/app/frontend/src/stores/auth.js index f24bdb57..d1fb1c67 100644 --- a/app/frontend/src/stores/auth.js +++ b/app/frontend/src/stores/auth.js @@ -3,18 +3,20 @@ import { useStorage } from '@vueuse/core' export const useAuthStore = defineStore('auth', () => { const user = useStorage('user', {}) - // const returnUrl = null const isLoggedIn = useStorage('isLoggedIn', false) - async function login(loginUser) { - this.isLoggedIn = true; - this.user = loginUser; + let storeToken = useStorage('storeToken', {}) + + async function login(token) { + // update pinia state + this.storeToken = token; } async function logout() { + this.user = {} this.isLoggedIn = false; - this.user = {}; + this.storeToken = {}; } return { isLoggedIn, user, login, logout } - }) \ No newline at end of file + })