Skip to content

Commit

Permalink
fix(auth): fix token refresh mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
NicolasRichel committed May 18, 2021
1 parent 2c21821 commit 13ff5ba
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 24 deletions.
25 changes: 17 additions & 8 deletions src/config/oidcConfig.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
/* This file is part of the BIMData Platform package.
(c) BIMData support@bimdata.io
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code. */
/**
* OIDC Client Configuration
* See: https://github.com/IdentityModel/oidc-client-js/wiki#configuration
*/

const APP_BASE_URL = process.env.VUE_APP_BASE_URL;
const AUTHORITY = `${process.env.VUE_APP_IAM_BASE_URL}/auth/realms/bimdata`;
const OIDC_ENDPOINT = `${AUTHORITY}/protocol/openid-connect`;
const CLIENT_ID = process.env.VUE_APP_OIDC_CLIENT_ID;

export const oidcConfig = {
// Auth request config
authority: AUTHORITY,
response_type: "code",
client_id: CLIENT_ID,
redirect_uri: `${APP_BASE_URL}/oidc-callback`,
scope: "openid profile email",
post_logout_redirect_uri: APP_BASE_URL,
response_type: "code",
redirect_uri: `${APP_BASE_URL}/oidc-callback`,
extraQueryParams: {
kc_idp_hint: "bimdataconnect"
},
automaticSilentRenew: true,

// Logout config
post_logout_redirect_uri: APP_BASE_URL,
revokeAccessTokenOnSignout: true,

// Enable access token refresh
automaticSilentRenew: true,

// Other options
clockSkew: 900,

// Auth metadata
metadata: {
issuer: AUTHORITY,
authorization_endpoint: `${OIDC_ENDPOINT}/auth`,
Expand Down
13 changes: 13 additions & 0 deletions src/server/AuthService.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,26 @@ class AuthServive {
);
}

signInSilent() {
return userManager.signinSilent();
}

signInCallback() {
return userManager.signinRedirectCallback();
}

signOut() {
return userManager.signoutRedirect();
}

onUserLoaded(callback) {
this._userLoadedCallback = callback;
userManager.events.addUserLoaded(callback);
}

offUserLoaded() {
userManager.events.removeUserLoaded(this._userLoadedCallback);
}
}

const service = new AuthServive();
Expand Down
26 changes: 17 additions & 9 deletions src/state/auth.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@ const state = reactive({
});

const authenticate = async redirectPath => {
const user = await AuthService.getUser();
if (user) {
if (!state.isAuthenticated) {
state.isAuthenticated = true;
state.accessToken = user.access_token;
}
} else {
let user = await AuthService.getUser();
if (!user) {
await AuthService.signIn(redirectPath);
return;
}
if (!state.isAuthenticated) {
if (user.expired) {
// Refresh access token silently
user = await AuthService.signInSilent();
}
// Keep access token up to date across refresh
AuthService.onUserLoaded(user => (state.accessToken = user.access_token));
// Set auth state
state.isAuthenticated = true;
state.accessToken = user.access_token;
}
};

Expand All @@ -30,11 +37,12 @@ const signInCallback = async () => {

const signOut = async () => {
await AuthService.signOut();
AuthService.offUserLoaded();
state.isAuthenticated = false;
state.user = null;
state.accessToken = null;
};

// Keep access token up to date across refresh
// Keep api client access token in sync with state
watchEffect(() => (apiClient.accessToken = state.accessToken));

export function useAuth() {
Expand Down
18 changes: 15 additions & 3 deletions src/views/model-viewer/ModelViewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<script>
import { merge, set } from "lodash";
import { onMounted, watch } from "vue";
import { onMounted, onUnmounted, watch } from "vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import makeBIMDataViewer from "@bimdata/viewer";
Expand Down Expand Up @@ -72,6 +72,9 @@ export default {
.map(pluginName => availablePlugins[pluginName])
.filter(Boolean); // keep only existing plugins
let unwatchAccessToken;
let unwatchLocale;
onMounted(async () => {
const bimdataViewer = makeBIMDataViewer({
api: {
Expand All @@ -97,8 +100,17 @@ export default {
const viewer = bimdataViewer.mount("#viewer", window);
watch(accessToken, token => viewer.setAccessToken(token));
watch(locale, lang => (viewer.$i18n.locale = lang));
unwatchAccessToken = watch(accessToken, token => {
viewer.setAccessToken(token);
});
unwatchLocale = watch(locale, lang => {
viewer.$i18n.locale = lang;
});
});
onUnmounted(() => {
unwatchAccessToken();
unwatchLocale();
});
}
};
Expand Down
7 changes: 3 additions & 4 deletions src/views/oidc-callback/OidcCallback.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ export default {
const router = useRouter();
const { signInCallback } = useAuth();
onMounted(() => {
signInCallback().then(result =>
router.push({ path: result.state ? result.state : "/" })
);
onMounted(async () => {
const result = await signInCallback();
router.push({ path: result.state ? result.state : "/" });
});
}
};
Expand Down

0 comments on commit 13ff5ba

Please sign in to comment.