feat: login page supports redirect_uri parameter (#3989)

#### What type of PR is this?

/area console
/kind feature
/milestone 2.6.x

#### What this PR does / why we need it:

Console 端的登录页面支持登录之后重定向到某个链接(通过 redirect_uri 参数)。

支持一下链接形式:

1. 相对地址,比如 `/console#/plugins`、`/apps/app-links`
2. 绝对地址,仅限于同源地址,不支持非同源地址的重定向。

#### Which issue(s) this PR fixes:

Fixes https://github.com/halo-dev/halo/issues/3982

#### Special notes for your reviewer:

测试方式:

1. 在未登录的情况下访问如 `http://127.0.0.1:8090/console#/theme` 地址,观察登录之后是否会返回到这个页面。
2. 手动在登录页面构造如 `https://127.0.0.1:8090/console#/login?redirect_uri=/` 的地址,观察登录之后是否会跳转。

#### Does this PR introduce a user-facing change?

```release-note
Console 端的登录页面支持登录之后重定向到某个站内链接。
```
pull/3983/head^2
Ryan Wang 2023-05-25 22:30:18 +08:00 committed by GitHub
parent 846138fe8c
commit 537d511cc0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 3 deletions

View File

@ -14,7 +14,9 @@ import { AppName } from "@/constants/app";
import { locales, getBrowserLanguage, i18n } from "@/locales";
import MdiTranslate from "~icons/mdi/translate";
import { useLocalStorage } from "@vueuse/core";
import { useRoute } from "vue-router";
const route = useRoute();
const userStore = useUserStore();
const { globalInfo } = useGlobalInfoFetch();
const { t } = useI18n();
@ -22,11 +24,42 @@ const { t } = useI18n();
const SIGNUP_TYPE = "signup";
onBeforeMount(() => {
if (!userStore.isAnonymous) {
router.push({ name: "Dashboard" });
if (userStore.isAnonymous) {
return;
}
if (allowRedirect()) {
window.location.href = route.query.redirect_uri as string;
return;
}
router.push({ name: "Dashboard" });
});
function allowRedirect() {
const redirect_uri = route.query.redirect_uri as string;
if (!redirect_uri || redirect_uri === window.location.href) {
return false;
}
if (redirect_uri.startsWith("/")) {
return true;
}
if (
redirect_uri.startsWith("https://") ||
redirect_uri.startsWith("http://")
) {
const url = new URL(redirect_uri);
if (url.origin === window.location.origin) {
return true;
}
}
return false;
}
function onLoginSucceed() {
window.location.reload();
}

View File

@ -13,7 +13,12 @@ export function setupAuthCheckGuard(router: Router) {
const userStore = useUserStore();
if (userStore.isAnonymous) {
next({ name: "Login" });
next({
name: "Login",
query: {
redirect_uri: from.path !== "/" ? window.location.href : undefined,
},
});
return;
}
next();