Vue js 与身份服务器 4 的集成

Vue js integration with identity server 4

我正在客户端实现 identity server 4vue js

目前,我在应用程序中只有管理员登录名,密码和用户名。

我没有任何 public 用户从中重定向到登录的站点。我希望用户在点击应用程序客户端 URL 时直接重定向到登录页面。

目前在 identity server 4 的示例版本中,用户需要点击导航栏上的登录按钮并重定向才能登录。

我想通过以下方式进行:

  1. 客户端点击 URL。检查用户是否通过身份验证。
  2. 重定向到身份服务器。
  3. 使用 Username/Password
  4. 登录
  5. 成功登录后重定向到客户端。

我很难将这种方法整合到 vue js 中。

在我当前的实现中,应用程序总是 运行 在循环中,并且总是被重定向到登录。

store.getters.isAuthenticated 永远不会是真的,它总是使用 SignIn 重定向应用程序。

我不知道我是否遗漏了 router.beforeEach 中的某些内容或 oidc.

的实施中的某些内容

路线:

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()
  }
})

登录组件:

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`,
}

登录:this.userManager.signinRedirect()

完成登录:this.userManager.signinRedirectCallback()

Silent.html:

new Oidc.UserManager().signinSilentCallback()
.catch(function (error) {
    console.error(error);
});

我不确定我是否正确理解了所有内容,而且我从未使用过 Vue。 但是让我描述一个我假设的典型隐式流程,你想在这里实现:

  1. 用户将在未经身份验证的情况下访问您的网站(例如 yoursite.com/dashboard
  2. AuthService 将尝试登录用户 - 即 he/she 将被重定向到身份服务器的登录页面
  3. 如果用户在身份服务器上没有有效会话 he/she 将提示输入凭据。否则 he/she 将立即重定向回您站点的请求重定向 uri(例如 yoursite.com/signin)。
  4. 此时用户已返回您的站点,但仍未登录。您会注意到 url 将在“#”字符后包含许多附加文本(例如 yoursite.com/singin#access_token=ey456...)
  5. 当您调用 completeLogin() 时 oidc-client 将读取此数据并将其保存(例如,在您的浏览器会话存储中)-此方法完成后,您的用户已登录,您可以重定向 him/her 到原始站点(例如 yoursite.com/dashboard

您可能在第 1 步到第 4 步之间遇到无限循环,因为您不允许第 5 步发生,所以登录永远不会完成。

尝试更改您的登录组件

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();
    }
};

还要确保即使 he/she 尚未通过身份验证,用户也可以访问登录组件,因此 he/she 可以完成登录过程。