I am implementing identity server 4
with vue js
in client side.
Currently, I have only the admin login in the application, with the password and username.
I do not have any public site from where the USER get redirected to login. I wanted the user get redirected to login page directly when they hit the application client URL.
Currently in the sample version of identity server 4
the user needs to hit the login button on the navbar and redirected to sign in.
I wanted to do in the following ways:
I have very hard time to integrate this approach in vue js
.
With my current implementation the application is always running in the loop and it is always redirected to sign in.
store.getters.isAuthenticated
is never true and it always redirecting the application with SignIn.
I couldn't figure out whether i have missed something in my router.beforeEach
or something in the implementation of oidc
.
Routes:
export const routes = [
{
component: Full,
path: "/",
meta: {
requiresAuth: true
},
children: [
{
path: "/dashboard",
name: "Dahboard",
component: DashboardView,
meta: {
requiresAuth: true
}
},
{
path: "/signin",
component: Signin
},
{
path: "/company",
component: Company,
meta: {
requiresAuth: true
}
}
]
}
];
import Vue from "vue";
import VueRouter from "vue-router";
import { routes } from "./routes";
import store from '../store'
Vue.use(VueRouter);
let router = new VueRouter({
mode: "history",
routes
});
export default router;
router.beforeEach((to, from, next) => {
if (store.getters.isAuthenticated) {
const notValid = ['/signin', '/signup']
if (notValid.lastIndexOf(to.path) >= 0) {
next({
path: '/dashboard'
})
} else if (to.path === '/signout') {
store.commit('removeAuthentication')
next({
path: '/'
})
} else {
next()
}
} else if (to.matched.some(record => record.meta.requiresAuth)) {
next({
path: '/signin',
query: {
redirect: to.fullPath
}
})
} else if (to.path === '/signout') {
next({
path: '/'
})
} else {
next()
}
})
SignIn Component:
import authService from './authService';
export default {
name: 'Auth',
mounted() {
authService.login();
authService.completeLogin();
}
};
Config.js
export default {
authority: "https://localhost:44350",
client_id: "js",
redirect_uri: `${domain}/signin`,
response_type: "id_token token",
scope:"openid profile api1",
post_logout_redirect_uri : `${domain}`,
silent_redirect_uri: `${domain}/silent.html`,
}
Login: this.userManager.signinRedirect()
completeLogin: this.userManager.signinRedirectCallback()
Silent.html:
new Oidc.UserManager().signinSilentCallback()
.catch(function (error) {
console.error(error);
});
I'm not sure I understand everything correctly and I never worked with Vue. But let me describe a typical implicit flow which I assume, you want to achieve here:
yoursite.com/dashboard
)yoursite.com/signin
).yoursite.com/singin#access_token=ey456...
)completeLogin()
oidc-client will read this data and save it (e.g. in your browsers session storage) - after this method completes, your user is logged in and you can redirect him/her to the original site (e.g. yoursite.com/dashboard
)You probably get an infinite loop between steps 1 - 4, because you never allow step 5 to happen, so the login never completes.
Try to change your signin component
import authService from './authService';
export default {
name: 'Auth',
mounted() {
//authService.login(); -- This line will redirect the user again before the login can complete
authService.completeLogin();
}
};
Also make sure the signin component can be accessed by the user even if he/she is not yet authenticated, so he/she can complete the login process.