Skip to content

Instantly share code, notes, and snippets.

@NathanWailes
Created April 4, 2022 17:53
Show Gist options
  • Save NathanWailes/fec671b9597fafe4e808d9070a73a8b9 to your computer and use it in GitHub Desktop.
Save NathanWailes/fec671b9597fafe4e808d9070a73a8b9 to your computer and use it in GitHub Desktop.
<template>
<router-view></router-view>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
interface AppFlowAccessTokenResponse {
access_token: string,
refresh_token: string
}
export default defineComponent({
name: 'App',
data () : {
authenticated: boolean,
authenticating: boolean
} {
return {
authenticated: false,
authenticating: false
}
},
methods: {
getAccessTokenTheGivenAuthorizationCode (gitHubAuthorizationCode: string): Promise<AppFlowAccessTokenResponse> {
const requestOptions = {
timeout: 30000
}
return this.$api.post('login/oauth/get-token', {
'code': gitHubAuthorizationCode
}, requestOptions)
.then((response: { data: AppFlowAccessTokenResponse }) => response.data)
},
sendTheBackendTheAuthorizationCodeFromGitHub (state: string | null, code: string) {
/* "By comparing the persisted state (in localStorage) to the state parameter from the redirection we are
protecting against a Cross-Site Request Forgery attack specific to OAuth 2.0 (and thus OpenID Connect)."
Source: https://codeburst.io/openid-connect-client-by-example-76caf6dae55e */
const storedState = window.localStorage.getItem('state')
window.localStorage.removeItem('state')
if (!(state === storedState)) {
throw "Stored state value doesn't match the value returned from GitHub."
}
this.getAccessTokenTheGivenAuthorizationCode(code).then((data) => {
const { access_token } = data
window.localStorage.setItem('access_token', access_token)
this.authenticated = true
}).catch((error) => {
console.log(error)
void this.$router.push({name: 'login'})
}).finally(() => {
this.authenticating = false
})
}
},
mounted () {
const params = new URL(document.location.toString()).searchParams
const state = params.get('state')
const code = params.get('code')
this.authenticating = code !== null
window.history.replaceState({}, document.title, '/')
const accessToken = window.localStorage.getItem('access_token')
this.authenticated = accessToken !== null
if (!this.authenticated && code !== null) {
this.sendTheBackendTheAuthorizationCodeFromGitHub(state, code)
} else if (!this.authenticated && !this.authenticating) {
void this.$router.push({name: 'login'})
}
},
watch: {
authenticated () {
if (!this.authenticated && !this.authenticating) {
void this.$router.push({name: 'login'})
} else if (this.authenticated && !this.authenticating) {
void this.$router.push({name: 'app'})
}
}
}
})
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment