Vue¶
Authany 帮助您为 Vue 应用添加用户登录功能。它提供了预构建的登录页面和用户设置页面,加快开发速度。
跟随这篇 15 分钟的教程,使用 Vue 和 Authany SDK 创建一个简单的应用。
说明
查看并克隆 GitHub 上的示例项目。
在 Authany 中设置应用¶
要使用 Authany,您需要一个 Authany 账号和一个项目。前往 https://manage.authany.com/ 注册免费账号并创建一个项目。
之后,我们需要在项目管理台中创建一个应用。
在管理台中创建应用¶
在这一步,我们将在 Authany 管理台中创建一个 Authany 客户端应用。后续步骤中我们会用到这个应用的配置,将 Vue 应用与 Authany 连接起来。
要创建客户端应用,在 Authany 管理台左侧菜单栏中导航到应用。

管理台导航到应用
接下来,点击顶部工具栏的 ⊕添加应用,打开新建应用页面。
输入应用名称,例如「MyAwesomeApp」,然后选择单页应用作为应用类型。
点击保存创建该应用。

创建新的客户端应用
在下一个页面,您会看到不同框架的教程链接。点击下一步跳过,进入应用配置页面
配置授权重定向 URI¶
重定向 URI 是您应用中的一个 URL,用户在 Authany 登录后会被重定向到这里。在这个路径中,需要发起一个完成身份验证调用来完成登录流程。
滚动到您在上一步创建的客户端应用配置页面的 URI 部分。在本教程中,将 http://localhost:4000/auth-redirect 添加到 Authorize Redirect URIs。
继续之前,点击保存按钮保存您的更改。

配置 Authorized Redirect URIs
将 Authany 添加到 Vue 应用¶
在这一部分,我们将把 Authany 添加到一个 Vue 应用中,使用 Authany JavaScript SDK 实现以下功能:
- 用户登录/注册
- 读取已登录用户的信息
- 打开用户设置页面
- 使用登出按钮结束用户会话
第 1 步:创建一个简单的 Vue 项目¶
以下是搭建 Vue 项目的一些推荐步骤。如果您是将 Authany 添加到现有项目中,可以跳过这部分,参见下一部分的第 3 步:将 Authany SDK 安装到项目中。
安装基本项目依赖¶
创建项目文件夹并安装依赖。我们将使用 Vite 作为构建工具,以及 vue-router 包。本教程中我们也会使用 TypeScript。
运行以下命令创建一个新项目:
创建项目并进入项目目录:
安装依赖:
安装 Vue router:
为开发模式添加端口配置¶
由于本教程使用 4000 端口,我们需要在配置中添加端口信息。在 vite.config.ts 文件中,按以下内容修改文件:
// vite.config.ts
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
server: {
port: 4000,
},
});
完成后,运行 npm run dev 时,服务器将运行在 4000 端口。
创建 Home.vue 文件¶
在 src/components 文件夹中创建一个名为 Home.vue 的新文件,只需在屏幕上显示 Hello World。将以下代码添加到 Home.vue:
// src/components/Home.vue
<script setup lang="ts"></script>
<template><div>Hello World</div></template>
编辑 App.vue 文件¶
App.vue 文件已经由 Vite 生成,但其中一些部分在本教程中可能用不上。将 App.vue 的内容编辑为以下内容:
// src/components/App.vue
<script setup lang="ts">
import Home from "./components/Home.vue";
</script>
<template>
<Home />
</template>
删除不需要的文件¶
有些文件可能用不到,因此可以删除。您可以执行以下脚本来删除这些文件:
文件结构¶
现在您项目中的文件结构是:
my-app
├── node_modules
│ └── (...)
├── package-lock.json
├── package.json
├── vite.config.ts
├── (...)
└── src
├── components
│ └── Home.vue
├── App.vue
├── main.ts
└── (...)
现在运行 npm run dev 来运行项目,您会在 http://localhost:4000 看到带有标题 Vite + Vue 的默认页面,以及一条 "Hello World" 消息。
第 2 步:为项目创建路由¶
在 src/components 文件夹中创建一个 AuthRedirect.vue 文件,此时内容与 src/components/Home.vue 相同。
在 src/ 文件夹中创建一个名为 router.ts 的文件。我们会导入 Home 和 AuthRedirect 组件作为路由,稍后再实现这些组件。该文件的内容如下:
// src/router.ts
import { createRouter, createWebHistory } from "vue-router";
export const history = createWebHistory();
export const router = createRouter({
history,
routes: [
{
path: "/",
// We will implement this component later
component: () => import("./components/Home.vue"),
},
{
path: "/auth-redirect",
// We will implement this component later
component: () => import("./components/AuthRedirect.vue"),
},
],
});
第 3 步:将 Authany SDK 安装到项目中¶
在您的 Vue 项目目录中运行以下命令,安装 Authany Web SDK
在 src/main.ts 中,导入 authgear 并调用 configure 函数,在应用加载时初始化一个 Authany 实例。我们还会导入 router,用它来为我们构建路由。您的 main.ts 文件应如下所示:
// src/main.ts
import { createApp } from "vue";
import './style.css'
import App from "./App.vue";
import { router } from "./router";
import authgear from "@authgear/web";
const app = createApp(App);
async function init() {
try {
// configure Authgear container instance
await authgear.configure({
endpoint: import.meta.env.VITE_AUTHGEAR_ENDPOINT,
clientID: import.meta.env.VITE_AUTHGEAR_CLIENT_ID,
sessionType: "refresh_token",
});
} finally {
app.use(router);
app.mount("#app");
}
}
init().catch((e) => {
// Error handling
console.error(e)
});
Authany 容器实例接受 endpoint 和 clientID 作为参数。它们可以从您在在 Authany 中设置应用中创建的应用页面获取。
在项目根目录创建一个 .env 文件,用以下字段添加您的 Authany 客户端应用配置:
VITE_AUTHGEAR_CLIENT_ID=<CLIENT_ID>
VITE_AUTHGEAR_ENDPOINT=<AUTHGEAR_ENDPOINT>
VITE_AUTHGEAR_REDIRECT_URL=http://localhost:4000/auth-redirect
建议在 configure() 解析完成后再渲染应用。这样,当应用渲染时,Authany 已经可以使用。
说明
现在运行 npm run dev,如果 Authany SDK 配置成功,您应该会看到同样的页面,并且控制台中没有错误信息
第 4 步:实现上下文提供者¶
由于我们希望在应用的任何地方都能引用登录状态,让我们在 /src/contexts 文件夹中用 UserProvider.vue 把该状态放进一个上下文提供者(context provider)中。
在 UserProvider.vue 中,会有一个 isLoggedIn 布尔值。isLoggedIn 这个布尔状态可以通过 onSessionStateChange 回调自动更新。该回调可以存储在本地 SDK 容器的 delegate 中。
// src/contexts/UserProvider.vue
<script lang="ts">
import {
defineComponent,
InjectionKey,
provide,
readonly,
ref,
Ref,
toRefs,
} from "vue";
import authgear from "@authgear/web";
export interface UserContextValue {
isLoggedIn: Ref<boolean>;
}
export const UserStateSymbol: InjectionKey<UserContextValue> =
Symbol("UserState");
export default defineComponent({
setup() {
const isLoggedIn = ref(false);
const state: UserContextValue = {
isLoggedIn,
};
authgear.delegate = {
onSessionStateChange: (container) => {
const sessionState = container.sessionState;
if (sessionState === "AUTHENTICATED") {
isLoggedIn.value = true;
} else {
isLoggedIn.value = false;
}
},
};
provide<UserContextValue>(UserStateSymbol, toRefs(readonly(state)));
return { state };
},
});
</script>
<template>
<slot />
</template>
第 5 步:实现身份验证重定向¶
接下来,我们会添加一个「AuthRedirect」页面,用于在用户通过 Authany 完成身份验证后处理验证结果。
在 src/components/ 文件夹中创建 AuthRedirect.vue 组件文件。
在 Auth Redirect 组件中调用 Authany 的 finishAuthentication() 函数,将令牌发回 Authany 服务器以换取访问令牌和刷新令牌。不用担心这些技术细节,finishAuthentication() 会替您完成所有繁重工作并保存身份验证数据。
身份验证完成后,UserContextProvider 中的 isLoggedIn 状态会自动被设为 true。最后,导航回根路径(/),也就是我们的首页。
最终的 AuthRedirect.vue 如下所示
// src/components/AuthRedirect.vue
<script setup lang="ts">
import { onMounted } from "vue";
import authgear from "@authgear/web";
import { router } from "../router";
onMounted(() => {
async function updateToken() {
try {
await authgear.finishAuthentication();
} finally {
router.replace({ path: "/" });
}
}
updateToken().catch((e) => console.error(e));
});
</script>
<template></template>
第 6 步:将路由和上下文提供者应用到应用中¶
由于我们已经在上一部分配置好了路由,现在只需在 App.vue 中添加 <router-view /> 标签即可。然后我们可以导入 UserProvider,并用它包裹 router-view。
您最终的 App.vue 应如下所示:
// src/App.vue
<script setup lang="ts">
import UserProvider from "./contexts/UserProvider.vue";
</script>
<template>
<UserProvider>
<router-view />
</UserProvider>
</template>
现在文件结构应如下所示
src
├── App.vue
├── main.ts
├── router.ts
├── vite-env.d.ts
├── contexts
│ └── UserProvider.vue
└── components
├── AuthRedirect.vue
└── Home.vue
第 7 步:添加登录按钮¶
首先,我们会导入 Authany 依赖。然后添加登录按钮,点击时会通过 startLogin 回调调用 startAuthentication(ConfigureOptions)。这会将用户重定向到登录页面。
// src/components/Home.vue
<script setup lang="ts">
import authgear, { PromptOption } from "@authgear/web";
const startLogin = () => {
authgear
.startAuthentication({
redirectURI: import.meta.env.VITE_AUTHGEAR_REDIRECT_URL,
prompt: PromptOption.Login,
})
.then(
() => {
// started authorization, user should be redirected to Authgear
},
(err) => {
// failed to start authorization
console.error(err);
}
);
};
</script>
<template>
<h1>Home Page</h1>
<button @click="startLogin">Login</button>
</template>
现在您可以运行 npm run dev,点击登录按钮后会被重定向到 Authany 登录页面。

第 8 步:显示用户信息¶
Authany SDK 可以帮助您轻松获取已登录用户的信息。
上一步中用户已成功登录,现在让我们尝试在首页打印用户的用户 ID(sub)。
在 Home.vue 中,我们会添加一个简单的加载提示,以及一条打印 Sub ID 的问候语。我们会添加两个条件元素,使它们仅在用户登录时显示。我们也可以让登录按钮仅在用户未登录时显示。
利用 UserProvider 中的 isLoggedIn 来控制页面上的组件。通过 fetchUserInfo() 获取用户信息,并访问其 sub 属性。
登录按钮同样可以做成条件渲染,仅在用户未登录时可见。
// src/components/Home.vue
<script setup lang="ts">
import authgear, { PromptOption } from "@authgear/web";
import { inject, onMounted, ref } from "vue";
import { UserStateSymbol } from "../contexts/UserProvider.vue";
const { isLoggedIn } = inject(UserStateSymbol)!;
const isLoading = ref(false);
const greetingMessage = ref("");
onMounted(() => {
async function updateGreetingMessage() {
isLoading.value = true;
try {
if (isLoggedIn.value) {
const userInfo = await authgear.fetchUserInfo();
greetingMessage.value = "The current User sub: " + userInfo.sub;
}
} finally {
isLoading.value = false;
}
}
updateGreetingMessage().catch((e) => {
console.error(e);
});
});
const startLogin = () => {
authgear
.startAuthentication({
redirectURI: import.meta.env.VITE_AUTHGEAR_REDIRECT_URL,
prompt: PromptOption.Login,
})
.then(
() => {
// started authorization, user should be redirected to Authgear
},
(err) => {
// failed to start authorization
console.error(err);
}
);
};
</script>
<template>
<h1>Home Page</h1>
<span v-if="isLoading">Loading...</span>
<span v-if="greetingMessage">{{ greetingMessage }}</span>
<div v-if="!isLoggedIn">
<button @click="startLogin">Login</button>
</div>
</template>
再次运行应用,页面上应该会打印出用户的用户 ID(sub)。
第 9 步:添加登出按钮¶
最后,让我们在用户登录后添加一个登出按钮。
在 Home.vue 的模板中,我们会添加以下条件元素:
并添加 logout 回调:
const logout = () => {
authgear
.logout({
redirectURI: "http://localhost:4000/",
})
.then(
() => {
greetingMessage.value = "";
},
(err) => {
console.error(err);
}
);
};
再次运行应用,我们现在可以点击登出按钮登出了。
第 10 步:打开用户设置¶
Authany 提供了一个内置 UI,供用户设置自己的属性和更改安全设置。
使用 open 函数打开 <your_app_endpoint>/settings 处的设置页面
在 Home.vue 中,在登出按钮部分后追加一个条件链接,如下所示:
<div v-if="isLoggedIn">
<button @click="logout()">Logout</button>
<br />
<a
target="_blank"
rel="noreferrer"
@click.stop.prevent="userSetting"
href="#"
>
User Setting
</a>
</div>
并添加 userSetting 回调:
import authgear, { PromptOption, Page } from "@authgear/web";
const userSetting = async () => {
await authgear.open(Page.Settings);
};
这是最终生成的 Home.vue:
// src/components/Home.vue
<script setup lang="ts">
import authgear, { PromptOption, Page } from "@authgear/web";
import { inject, onMounted, ref } from "vue";
import { UserStateSymbol } from "../contexts/UserProvider.vue";
const { isLoggedIn } = inject(UserStateSymbol)!;
const isLoading = ref(false);
const greetingMessage = ref("");
onMounted(() => {
async function updateGreetingMessage() {
isLoading.value = true;
try {
if (isLoggedIn.value) {
const userInfo = await authgear.fetchUserInfo();
greetingMessage.value = "The current User sub: " + userInfo.sub;
}
} finally {
isLoading.value = false;
}
}
updateGreetingMessage().catch((e) => {
console.error(e);
});
});
const startLogin = () => {
authgear
.startAuthentication({
redirectURI: import.meta.env.VITE_AUTHGEAR_REDIRECT_URL,
prompt: PromptOption.Login,
})
.then(
() => {
// started authorization, user should be redirected to Authgear
},
(err) => {
// failed to start authorization
console.error(err);
}
);
};
const logout = () => {
authgear
.logout({
redirectURI: "http://localhost:4000/",
})
.then(
() => {
greetingMessage.value = "";
},
(err) => {
console.error(err);
}
);
};
const userSetting = async () => {
await authgear.open(Page.Settings);
};
</script>
<template>
<h1>Home Page</h1>
<span v-if="isLoading">Loading...</span>
<span v-if="greetingMessage">{{ greetingMessage }}</span>
<div v-if="!isLoggedIn">
<button @click="startLogin">Login</button>
</div>
<div v-if="isLoggedIn">
<button @click="logout">Logout</button>
<br />
<a
target="_blank"
rel="noreferrer"
@click.stop.prevent="userSetting"
href="#"
>
User Setting
</a>
</div>
</template>

下一步,调用 API¶
要访问后端应用服务器上的受限资源,HTTP 请求的 Authorization 请求头中应包含访问令牌。Web SDK 提供了一个 fetch 函数,会自动处理这一点,您也可以通过 authgear.accessToken 获取该令牌。
方式一:使用 Authany SDK 提供的 fetch 函数¶
Authany SDK 为您提供了 fetch 函数,用于调用您的应用服务器。这个 fetch 函数会在您的应用请求中自动带上 Authorization 请求头,并自动处理刷新访问令牌。authgear.fetch 实现了 fetch。
authgear
.fetch("YOUR_SERVER_URL")
.then(response => response.json())
.then(data => console.log(data));
方式二:将访问令牌添加到 HTTP 请求头¶
您可以通过 authgear.accessToken 获取访问令牌。每次使用访问令牌之前都调用 refreshAccessTokenIfNeeded,该函数只会在访问令牌已过期时才检查并发起网络请求。将访问令牌加入应用请求的 Authorization 请求头中。
authgear
.refreshAccessTokenIfNeeded()
.then(() => {
// access token is ready to use
// accessToken can be string or undefined
// it will be empty if user is not logged in or session is invalid
const accessToken = authgear.accessToken;
// include Authorization header in your application request
const headers = {
Authorization: `Bearer ${accessToken}`
};
});