Some wprk on auth code
This commit is contained in:
28
KTUSA PS/ClientApp/package-lock.json
generated
28
KTUSA PS/ClientApp/package-lock.json
generated
@@ -2104,6 +2104,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"@vue/devtools-api": {
|
||||
"version": "6.0.0-beta.15",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.15.tgz",
|
||||
"integrity": "sha512-quBx4Jjpexo6KDiNUGFr/zF/2A4srKM9S9v2uHgMXSU//hjgq1eGzqkIFql8T9gfX5ZaVOUzYBP3jIdIR3PKIA=="
|
||||
},
|
||||
"@vue/preload-webpack-plugin": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/preload-webpack-plugin/-/preload-webpack-plugin-1.1.2.tgz",
|
||||
@@ -3812,6 +3817,11 @@
|
||||
"integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
|
||||
"dev": true
|
||||
},
|
||||
"cookies-js": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/cookies-js/-/cookies-js-1.2.3.tgz",
|
||||
"integrity": "sha1-AzFQSefFK+4/cxhqaRZ+qw3bLTE="
|
||||
},
|
||||
"copy-concurrently": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz",
|
||||
@@ -7049,6 +7059,16 @@
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"jsrsasign": {
|
||||
"version": "10.3.0",
|
||||
"resolved": "https://registry.npmjs.org/jsrsasign/-/jsrsasign-10.3.0.tgz",
|
||||
"integrity": "sha512-irDIKKFW++EAELgP3fjFi5/Fn0XEyfuQTTgpbeFwCGkV6tRIYZl3uraRea2HTXWCstcSZuDaCbdAhU1n+075Bg=="
|
||||
},
|
||||
"jwt-decode": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-3.1.2.tgz",
|
||||
"integrity": "sha512-UfpWE/VZn0iP50d8cz9NrZLM9lSWhcJ+0Gt/nm4by88UL+J1SiKN8/5dkjMmbEzwL2CAe+67GsegCbIKtbp75A=="
|
||||
},
|
||||
"killable": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
|
||||
@@ -11307,6 +11327,14 @@
|
||||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"dev": true
|
||||
},
|
||||
"vuex": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||
"integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.11"
|
||||
}
|
||||
},
|
||||
"watchpack": {
|
||||
"version": "1.7.5",
|
||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.5.tgz",
|
||||
|
@@ -10,10 +10,13 @@
|
||||
"dependencies": {
|
||||
"axios": "^0.20.0-0",
|
||||
"bootstrap": "^4.5.3",
|
||||
"cookies-js": "^1.2.3",
|
||||
"core-js": "^3.7.0",
|
||||
"jwt-decode": "^3.1.2",
|
||||
"vue": "^3.0.2",
|
||||
"vue-loader-v16": "npm:vue-loader@^16.0.0-alpha.3",
|
||||
"vue-router": "^4.0.0-rc.5"
|
||||
"vue-router": "^4.0.0-rc.5",
|
||||
"vuex": "^4.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vue/cli-plugin-babel": "^4.5.9",
|
||||
|
@@ -4,14 +4,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import NavMenu from './components/NavMenu.vue'
|
||||
import NavMenu from "./components/NavMenu.vue";
|
||||
|
||||
export default {
|
||||
name: 'App',
|
||||
name: "App",
|
||||
components: {
|
||||
NavMenu
|
||||
}
|
||||
}
|
||||
NavMenu,
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch("auth/loadToken");
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@@ -1,75 +1,97 @@
|
||||
<template>
|
||||
<header>
|
||||
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
|
||||
<div class="container">
|
||||
<a class="navbar-brand">Vue JS Template for .NET 5</a>
|
||||
<button class="navbar-toggler"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target=".navbar-collapse"
|
||||
aria-label="Toggle navigation"
|
||||
@click="toggle">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"
|
||||
v-bind:class="{show: isExpanded}">
|
||||
<ul class="navbar-nav flex-grow">
|
||||
<li class="nav-item">
|
||||
<router-link :to="{ name: 'Home' }" class="nav-link text-dark">Home</router-link>
|
||||
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link :to="{ name: 'Counter' }" class="nav-link text-dark">Counter</router-link>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link :to="{ name: 'FetchData' }" class="nav-link text-dark">Fetch Data</router-link>
|
||||
</li>
|
||||
<a href="https://login.microsoftonline.com/3415f2f7-f5a8-4092-b52a-003aaf844853/oauth2/v2.0/authorize?client_id=5931fda0-e9e0-4754-80c2-18bcb9d9561a&response_type=id_token&scope=openid email&nonce=aaaa">Login</a>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
<header>
|
||||
<nav
|
||||
class="
|
||||
navbar navbar-expand-sm navbar-toggleable-sm navbar-light
|
||||
bg-white
|
||||
border-bottom
|
||||
box-shadow
|
||||
mb-3
|
||||
"
|
||||
>
|
||||
<div class="container">
|
||||
<a class="navbar-brand">Vue JS Template for .NET 5</a>
|
||||
<button
|
||||
class="navbar-toggler"
|
||||
type="button"
|
||||
data-toggle="collapse"
|
||||
data-target=".navbar-collapse"
|
||||
aria-label="Toggle navigation"
|
||||
@click="toggle"
|
||||
>
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
<div
|
||||
class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse"
|
||||
v-bind:class="{ show: isExpanded }"
|
||||
>
|
||||
<ul class="navbar-nav flex-grow">
|
||||
<li class="nav-item">
|
||||
<router-link :to="{ name: 'Home' }" class="nav-link text-dark"
|
||||
>Home</router-link
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link :to="{ name: 'Counter' }" class="nav-link text-dark"
|
||||
>Counter</router-link
|
||||
>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<router-link
|
||||
:to="{ name: 'FetchData' }"
|
||||
class="nav-link text-dark"
|
||||
>Fetch Data</router-link
|
||||
>
|
||||
</li>
|
||||
<a
|
||||
href="https://login.microsoftonline.com/3415f2f7-f5a8-4092-b52a-003aaf844853/oauth2/v2.0/authorize?client_id=5931fda0-e9e0-4754-80c2-18bcb9d9561a&response_type=id_token&scope=openid email profile&nonce=aaaa"
|
||||
>Login</a
|
||||
>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
|
||||
<style>
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
a.navbar-brand {
|
||||
white-space: normal;
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
html {
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
@media (min-width: 768px) {
|
||||
html {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.box-shadow {
|
||||
box-shadow: 0 .25rem .75rem rgba(0, 0, 0, .05);
|
||||
}
|
||||
.box-shadow {
|
||||
box-shadow: 0 0.25rem 0.75rem rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
export default {
|
||||
name: "NavMenu",
|
||||
data() {
|
||||
return {
|
||||
isExpanded: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
collapse() {
|
||||
this.isExpanded = false;
|
||||
},
|
||||
export default {
|
||||
name: "NavMenu",
|
||||
data() {
|
||||
return {
|
||||
isExpanded: false,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
collapse() {
|
||||
this.isExpanded = false;
|
||||
},
|
||||
|
||||
toggle() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
}
|
||||
}
|
||||
}
|
||||
toggle() {
|
||||
this.isExpanded = !this.isExpanded;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
@@ -1,6 +1,10 @@
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import "bootstrap/dist/css/bootstrap.css";
|
||||
import { createApp } from "vue";
|
||||
import App from "./App.vue";
|
||||
import router from "./router";
|
||||
import store from "./store";
|
||||
|
||||
createApp(App).use(router).mount('#app')
|
||||
const app = createApp(App);
|
||||
app.use(router);
|
||||
app.use(store);
|
||||
app.mount("#app");
|
||||
|
14
KTUSA PS/ClientApp/src/pages/Home.vue
Normal file
14
KTUSA PS/ClientApp/src/pages/Home.vue
Normal file
@@ -0,0 +1,14 @@
|
||||
<template>
|
||||
<h1>Hello there</h1>
|
||||
<!-- {{ $store.state.auth.tokenData }} -->
|
||||
{{ $store.getters["auth/isValid"] }}
|
||||
<br />
|
||||
Your name is: {{ $store.getters["auth/name"] }}<br />
|
||||
Your email is: {{ $store.getters["auth/email"] }}<br />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "Home page",
|
||||
};
|
||||
</script>
|
@@ -7,6 +7,8 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// https://login.microsoftonline.com/3415f2f7-f5a8-4092-b52a-003aaf844853/oauth2/v2.0/authorize?client_id=5931fda0-e9e0-4754-80c2-18bcb9d9561a&response_type=id_token&scope=openid email&nonce=a
|
||||
|
||||
const tokenRegex = /id_token=(.*\..*\..*)&/;
|
||||
import axios from "axios";
|
||||
|
||||
@@ -17,16 +19,19 @@ export default {
|
||||
response: "[empty]",
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.$store.dispatch("auth/setToken", this.openIdToken);
|
||||
},
|
||||
methods: {
|
||||
makeTestCall() {
|
||||
axios
|
||||
.get("/test", {
|
||||
headers: { Authorization: `Bearer ${this.openIdToken}` }
|
||||
headers: { Authorization: `Bearer ${this.openIdToken}` },
|
||||
})
|
||||
.then((response) => {
|
||||
this.response = response.data;
|
||||
})
|
||||
.catch(function(error) {
|
||||
.catch(function (error) {
|
||||
alert(error);
|
||||
});
|
||||
},
|
||||
|
@@ -1,35 +1,35 @@
|
||||
import { createWebHistory, createRouter } from "vue-router";
|
||||
import Home from "@/components/Home.vue";
|
||||
import Home from "@/pages/Home.vue";
|
||||
import Counter from "@/components/Counter.vue";
|
||||
import FetchData from "@/components/FetchData.vue";
|
||||
import OidcEndpoint from "@/pages/OidcEndpoint.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
},
|
||||
{
|
||||
path: "/Counter",
|
||||
name: "Counter",
|
||||
component: Counter,
|
||||
},
|
||||
{
|
||||
path: "/FetchData",
|
||||
name: "FetchData",
|
||||
component: FetchData,
|
||||
},
|
||||
{
|
||||
path: "/oidc",
|
||||
name: "OpenID connect endpoint",
|
||||
component: OidcEndpoint,
|
||||
},
|
||||
{
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
},
|
||||
{
|
||||
path: "/Counter",
|
||||
name: "Counter",
|
||||
component: Counter,
|
||||
},
|
||||
{
|
||||
path: "/FetchData",
|
||||
name: "FetchData",
|
||||
component: FetchData,
|
||||
},
|
||||
{
|
||||
path: "/oidc",
|
||||
name: "OpenID connect endpoint",
|
||||
component: OidcEndpoint,
|
||||
},
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
|
||||
export default router;
|
12
KTUSA PS/ClientApp/src/store/index.js
Normal file
12
KTUSA PS/ClientApp/src/store/index.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import { createStore, createLogger } from "vuex";
|
||||
import auth from "./modules/auth";
|
||||
|
||||
const debug = process.env.NODE_ENV !== "production";
|
||||
|
||||
export default createStore({
|
||||
modules: {
|
||||
auth,
|
||||
},
|
||||
strict: debug,
|
||||
plugins: debug ? [createLogger()] : [],
|
||||
});
|
75
KTUSA PS/ClientApp/src/store/modules/auth.js
Normal file
75
KTUSA PS/ClientApp/src/store/modules/auth.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import Cookies from "cookies-js";
|
||||
import jwt_decode from "jwt-decode";
|
||||
const TokenCookieName = "ktusaktutoken";
|
||||
|
||||
// initial state
|
||||
const state = () => ({
|
||||
token: null,
|
||||
tokenData: null,
|
||||
});
|
||||
|
||||
// getters
|
||||
const getters = {
|
||||
isValid(state) {
|
||||
if (state.token == null || state.tokenData == null) return false;
|
||||
const d = state.tokenData;
|
||||
if (
|
||||
d.iss !==
|
||||
"https://login.microsoftonline.com/3415f2f7-f5a8-4092-b52a-003aaf844853/v2.0"
|
||||
)
|
||||
return false;
|
||||
|
||||
if (d.aud !== "5931fda0-e9e0-4754-80c2-18bcb9d9561a") return false;
|
||||
const now = new Date();
|
||||
const exp = new Date(d.exp * 1000);
|
||||
if (now > exp) return false;
|
||||
return true;
|
||||
},
|
||||
name(state, getters) {
|
||||
if (!getters.isValid) return null;
|
||||
return state.tokenData.name;
|
||||
},
|
||||
email(state, getters) {
|
||||
if (!getters.isValid) return null;
|
||||
return state.tokenData.email;
|
||||
},
|
||||
};
|
||||
|
||||
// actions
|
||||
const actions = {
|
||||
async loadToken({ commit }) {
|
||||
const token = Cookies.get(TokenCookieName);
|
||||
commit("setToken", token);
|
||||
commit("computeTokenVars");
|
||||
},
|
||||
async setToken({ commit }, token) {
|
||||
Cookies.set(TokenCookieName, token);
|
||||
commit("setToken", token);
|
||||
commit("computeTokenVars");
|
||||
},
|
||||
};
|
||||
|
||||
// mutations
|
||||
const mutations = {
|
||||
setToken(state, token) {
|
||||
state.token = token;
|
||||
},
|
||||
computeTokenVars(state) {
|
||||
if (state.token == null) return;
|
||||
try {
|
||||
state.tokenData = jwt_decode(state.token);
|
||||
} catch {
|
||||
console.log("Token was invalid.");
|
||||
state.tokenData = null;
|
||||
state.token = null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
export default {
|
||||
namespaced: true,
|
||||
state,
|
||||
getters,
|
||||
actions,
|
||||
mutations,
|
||||
};
|
Reference in New Issue
Block a user