龙空技术网

如何在具有自己 UI 的 VueJS 应用程序中使用 SuperTokens

科技狠活与软件技术 329

前言:

而今小伙伴们对“div填充20px”大约比较关注,各位老铁们都想要学习一些“div填充20px”的相关文章。那么小编同时在网上搜集了一些有关“div填充20px””的相关资讯,希望小伙伴们能喜欢,大家快快来学习一下吧!

@头条创作挑战赛

每日分享最新,最流行的软件开发知识与最新行业趋势,希望大家能够一键三连,多多支持,跪求关注,点赞,留言。

这篇文章将指导您如何使用您自己的 UI 使用 SuperTokens 向 VueJS 应用程序添加身份验证。我们将构建我们自己的身份验证表单,并将supertokens-web-js用于使这些表单工作。

什么是SuperTokens?

SuperTokens 是一个开源项目,可让您快速将身份验证添加到您的应用程序。它提供了各种身份验证方法(称为配方)。

除了预构建的 UI,它还提供了一个名为 vanilla JS SDK supertokens-web-js,您可以使用它来构建自己的 UI。在本教程中,我们将学习如何使用supertokens-web-jsVueJS 应用程序添加身份验证。我们将专注于电子邮件密码和社交登录流程,但您也可以选择另一种身份验证方法。

Architechture

SuperTokens 由三个组件构成:

前端 SDK

后端 SDK

与数据库对话的微服务(称为 SuperTokens Core)。

我们将构建自己的登录、注册和重置密码表单。然后,我们将supertokens-web-js在我们的 Vue 应用程序中使用 SDK,通过为每个操作调用相关函数来使这些表单发挥作用。这些函数将与集成到后端层的 SuperTokens SDK 的 API 交互。

对于后端,我们将使用supertokens-nodeSDK。此 SDK 公开的 API 将进一步与 SuperTokens Core 对话,以读取/写入数据库的信息。

SuperTokens 核心服务可以是自托管的(并连接到您自己的数据库)或由 SuperTokens 背后的团队托管(在 supertokens.com 上注册)。在博客中,我们将使用托管在

前端

首先创建一个新的 Vue 应用程序:

npm init vue@latest

我们将为项目启用 Vue Router 和 Typescript。在提示中为他们选择是:

✔ Project name: … <your-project-name>

...

✔ Add TypeScript? … Yes

✔ Add Vue Router for Single Page Application development? … Yes

...

Scaffolding project in ./<your-project-name>...

Done.

完成后,进入项目并安装以下依赖项:

npm i supertokens-node supertokens-web-js cors dotenv express npm-run-all

该supertokens-web-js库将在前端用于向您的自定义 UI 添加身份验证和重置密码功能。该supertokens-node库将在后端用于公开身份验证 API 路由。

调用supertokens-web-js init函数

我们将supertokens-web-js在 Vue 应用程序的根文件中初始化 SDK,即/src/main.ts:

import ThirdPartyEmailPassword from "supertokens-web-js/recipe/thirdpartyemailpassword";

import Session from "supertokens-web-js/recipe/session";

SuperTokens.init({

appInfo: {

appName: "SuperTokens Vue ThirdPartyEmailPassword Example",

apiDomain: ";,

},

recipeList: [ThirdPartyEmailPassword.init(), Session.init()],

});

在上面的代码中,init函数在前端初始化supertokens-web-js。我们在应用程序的根文件中调用此函数以在整个应用程序中使用会话管理功能。它还指示了我们想要使用的身份验证类型——在我们的例子中;这是社交登录名+电子邮件密码(ThirdPartyEmailPassword配方)。

创建AuthViewHTML 模板

我们将从创建呈现注册和登录的 HTML 模板开始作为示例;你可以参考这个 HTML 模板。

模板文件调用以下函数来处理社交登录和使用电子邮件和密码的注册/登录:

onGithubPressed:此功能允许用户通过其 Github 帐户进行身份验证

onGooglePressed:此功能允许用户通过其 Google 帐户进行身份验证

onSubmitPressed:当用户输入他们的电子邮件和密码以注册或登录时触发此功能。

创建 AuthView 状态和模板函数

我们将在一个AuthView组件中呈现这个 HTML 模板,/src/views/AuthView.vue,其中还将包含上述函数的实现:

<template src="../html/authView.html"></template>

我们将首先创建状态来存储用于身份验证的数据,例如我们的模板的电子邮件、密码和错误消息:

// ...

data() {

return {

// we allow the user to switch between sign in and sign up view

isSignIn: true,

// this will store the email and password entered by the user.

email: "",

password: "",

// any generic error states

error: false,

errorMessage: "Something went wrong",

// any error states specific to the input fields.

emailError: "",

passwordError: "",

};

}

然后我们将创建一个signIn使用supertokens-web-jsSDK 的函数。

如果身份验证成功,我们会将电子邮件和密码传递给此方法,并将用户重定向到“/”路由。如果状态为signIn,将从函数调用此函数。 onSubmitPressedisSignIntrue

signIn: async function (_: Event) {

const response = await ThirdPartyEmailPassword.emailPasswordSignIn({

formFields: [

{

id: "email",

value: this.email,

},

{

id: "password",

value: this.password,

},

],

});

if (response.status === "WRONG_CREDENTIALS_ERROR") {

// the input email / password combination did not match,

// so we show an appropriate error message to the user

this.errorMessage = "Invalid credentials";

this.error = true;

return;

}

if (response.status === "FIELD_ERROR") {

response.formFields.forEach((item) => {

if (item.id === "email") {

// this means that something was wrong with the entered email.

// probably that it's not a valid email (from a syntax point of view)

this.emailError = item.error;

} else if (item.id === "password") {

this.passwordError = item.error;

}

});

return;

}

// login is successful, and we redirect the user to the home page.

// Note that session cookies are added automatically and nothing needs to be

// done here about them.

window.location.assign("/");

}

如果status响应正文中的字段是"FIELD_ERROR",并且id是"email",则表示用户输入的字符串未通过后端的电子邮件验证(很可能是因为它不是有效的电子邮件)。所以我们存储错误状态并在 UI 上向用户显示错误消息。以下是如何使错误消息显示在电子邮件字段下方的示例:

无效的电子邮件错误

同样,我们可以实现signUp调用emailPasswordSignUp函数的方法supertokens-web-js来处理注册流程。

对于社交登录,我们使用 Google 和 Github 身份验证提供程序。当onGithubPressed或onGooglePressed函数被调用时,我们调用getAuthorisationURLWithQueryParamsAndSetState方法并在参数中传递提供者名称。我们还提供一个回调 URL 作为authorisationURL参数,提供者将在身份验证过程完成后重定向回该参数。在我们的示例中,我们使用 和。

这些 URL 也需要在提供商的仪表板上进行配置。

下面分别是 GitHub 和 Google 的函数:

onGithubPressed: async function () {

const authUrl = await ThirdPartyEmailPassword.getAuthorisationURLWithQueryParamsAndSetState({

providerId: "github",

// This is where github should redirect the user back after login or error.

// This URL goes on the github dashboard as well.

authorisationURL: ";,

});

window.location.assign(authUrl);

},

onGooglePressed: async function () {

const authUrl = await ThirdPartyEmailPassword.getAuthorisationURLWithQueryParamsAndSetState({

providerId: "google",

// This is where google should redirect the user back after login or error.

// This URL goes on the google dashboard as well.

authorisationURL: ";,

});

window.location.assign(authUrl);

}

用户在提供商的网站上完成身份验证后,将被重定向到该;provider>路由。在这里,我们调用使用授权代码(从提供者发回)的thirdPartySignInAndUp函数来登录用户。supertokens-web-js,

AuthCallbackView该函数在组件内部/src/views/AuthCallbackView.vue文件中处理上述流程:

mounted: async function () {

try {

const response = await ThirdPartyEmailPassword.thirdPartySignInAndUp();

if (response.status !== "OK") {

// either the user did not complete the login process, or something else went wrong.

return window.location.assign("/auth?error=signin");

}

// sign in successful.

// The session tokens are handled automatically via our SDK.

window.location.assign("/");

} catch (_) {

window.location.assign("/auth?error=signin");

}

}

设置路由以显示注册/登录表单

Vue CLI 已经为我们的应用生成了初始路由/src/router.index.ts。

我们将更新这个文件,以便/auth路由加载AuthView组件并且/auth/callback/:provider路由加载AuthCallbackView我们之前创建的组件:

import { createRouter, createWebHistory } from "vue-router";

import AuthView from "../views/AuthView.vue";

const router = createRouter({

history: createWebHistory(import.meta.env.BASE_URL),

routes: [

{

path: "/auth",

name: "auth",

component: () => AuthView,

},

{

path: "/auth/callback/:provider",

name: "authcallback",

component: () => AuthCallbackView,

}

],

});

export default router;

后端集成

您可以在我们的文档中查看后端快速设置部分,甚至可以从我们的示例应用程序中复制代码。作为总结:

您需要初始化supertokens-nodeSDK 并提供它recipeList(类似于您在前端所做的)。

然后您需要设置CORSSuperTokensmiddleware并将其添加errorHandler到您的应用程序中。SuperTokens 向前端middleware公开所有与身份验证相关的 API 路由(如登录、注册、注销等)。

最后,您需要提供connectionURISuperTokens 核心的(位置)。为了快速开始,您可以提供它";(这是我们为演示目的而托管的核心)。

成功设置服务器后,您现在可以尝试在前端注册。

会话管理

认证后,我们会HomeView在页面里面渲染一个组件/src/views/HomeView.vue。首先,我们将在以下位置创建 HTML 模板/src/html/homeView.html:

<div v-if="session">

<div class="fill">

<div class="top-bar">

<div class="sign-out" v-on:click="signOut">SIGN OUT</div>

</div>

<div class="fill home-content">

<span class="home-emoji"></span>

Login successful

<div style="height: 20px" />

Your user ID is <br />

{{ `${userId}` }}

<div style="height: 40px" />

<div class="session-button" v-on:click="callAPI">CALL API</div>

<div style="height: 30px" />

------------------------------------

<div style="height: 40px" />

<a

href=";

target="_blank"

rel="noreferrer">

View the code on GitHub

</a>

</div>

<div class="bottom-banner">Vue Demo app. Made with <3 using supertokens.com</div>

</div>

</div>

然后在内部 /src/views/HomeView.vue,我们将使用SDKdoesSessionExist中的 Session 配方公开的方法检查用户是否已通过身份验证。supertokens-web-js

我们为经过身份验证的用户呈现一个注销按钮,其中包含有关他们会话的信息。当用户单击此按钮时,我们调用清除用户会话的signOut方法。supertokens-web-js,

对于未经身份验证的用户,我们可以将他们重定向到/auth页面。

<script lang="ts">

import { defineComponent } from "vue";

import Session from "supertokens-web-js/recipe/session";

import ThirdPartyEmailPassword from "supertokens-web-js/recipe/thirdpartyemailpassword";

const apiPort = import.meta.env.VUE_APP_API_PORT || 3001;

const apiDomain = import.meta.env.VUE_APP_API_URL || `{apiPort}`;

export default defineComponent({

data() {

return {

// if session is false, we show a blank screen

// else we render the UI

session: false,

userId: "",

};

},

methods: {

signOut: async function () {

await ThirdPartyEmailPassword.signOut();

window.location.assign("/auth");

},

checkForSession: async function () {

if (!(await Session.doesSessionExist())) {

// since a session does not exist, we send the user to the login page.

return window.location.assign("/auth");

}

const userId = await Session.getUserId();

// this will render the UI

this.session = true;

this.userId = userId;

},

callAPI: async function () {

const response = await fetch(`${apiDomain}/sessionInfo`);

if (response.status === 401) {

// this means that the session has expired and the

// user needs to relogin.

window.location.assign("/auth");

return;

}

const json = await response.json();

window.alert("Session Information:

" + JSON.stringify(json, null, 2));

},

},

mounted() {

// this function checks if a session exists, and if not,

// it will redirect to the login screen.

this.checkForSession();

},

});

</script>

<template src="../html/homeView.html"></template>

对于/auth路由,如果会话已经存在,我们会将用户重定向到主页:

checkForSession: async function () {

if (await Session.doesSessionExist()) {

// since a session already exists, we redirect the user to the HomeView.vue component

window.location.assign("/");

}

},

最后,要加载HomeView组件,"/"我们将更新/src/router/index.ts文件:

const router = createRouter({

history: createWebHistory(import.meta.env.BASE_URL),

routes: [

{

path: "/",

name: "home",

component: () => HomeView,

},

// ...

],

});

export default router;

如果您现在在身份验证后访问这里,您应该会看到以下页面:

登录后的主页视图

忘记密码流程

在登录 UI 中,我们有一个指向忘记密码页面的链接。用户可以输入他们的电子邮件并在此页面的收件箱中接收密码重置链接。当他们访问该链接时,他们可以在该页面上输入新密码以更改密码。

首先,我们将在内部创建 HTML 模板 /src/html/forgotPassword.html。这是您可以使用的示例。

我们将在/src/views/ForgotPassword.vue文件中创建一个组件,我们将在其中呈现上述模板:

<template src="../html/forgotPassword.html"></template>

在 HTML 模板中,我们根据名为 的变量有条件地呈现表单,该变量tokenPresent是一个状态变量,表示是否已生成密码重置令牌。此tokenPresent变量是根据页面 URL 的查询参数中存在的令牌设置的。如果用户点击了忘记密码按钮(在登录页面上),则页面 URL 的查询参数中不存在令牌;因此tokenPresent变量设置为false。

由于tokenPresentis false,我们呈现表单,用户将在其中输入他们的电子邮件以获取重置密码链接。当用户在此表单上输入他们的电子邮件并提交时,我们调用sendPasswordResetEmail方法 fromsupertokens-web-js并传入他们的电子邮件。如果该电子邮件存在于 SuperTokens 中,此函数与后端 API 交互以向用户的电子邮件发送密码重置链接。

密码重置链接就像;rid=thirdpartyemailpassword. 此链接与忘记密码页面的路径相同;但是,由于 URL 具有token查询参数,它应该呈现用户可以输入新密码的表单。

当他们在表单中输入新密码时,我们submitNewPassword使用新密码调用该函数。该函数会自动从 URL 中读取令牌并调用 SuperTokens 后端 API 来更改用户的密码。

如果密码重置令牌已被使用或已过期,函数调用将返回非"OK"状态,然后我们可以在 UI 上显示消息以提示用户返回登录屏幕。

<script lang="ts">

import ThirdPartyEmailPassword from "supertokens-web-js/recipe/thirdpartyemailpassword";

import { defineComponent } from "vue";

export default defineComponent({

data() {

/**

* If the URL has a token query param, it means that we should show the

* "enter new password" screen, else we should ask the user for their email

* to send the password reset link.

*/

const urlParams = new URLSearchParams(window.location.search);

const token = urlParams.get("token");

return {

// the email property is used for the enter email screen

email: "",

error: false,

errorMessage: "Something Went Wrong",

didSubmit: false,

// if tokenPresent is true, it means that the user has clicked on the

// reset password link.

tokenPresent: token !== null,

password: "",

};

},

methods: {

onSubmitClicked: async function () {

if (this.tokenPresent) {

// we try and change the user's password now by consuming the token

try {

const response = await ThirdPartyEmailPassword.submitNewPassword({

formFields: [

{

id: "password",

value: this.password,

},

],

});

if (response.status === "FIELD_ERROR") {

// this indicates that the password entered by the user

// did not match the backend password validation logic.

throw new Error(response.formFields[0].error);

} else if (response.status === "RESET_PASSWORD_INVALID_TOKEN_ERROR") {

// the password reset token was consumed already, or has expired.

// in this case, the user should go back to the login screen or the

// enter email screen

throw new Error("Password reset token has expired, please go back to the sign in page");

}

// password reset successful.

window.location.assign("/auth");

} catch (e: any) {

this.errorMessage = e.message;

this.error = true;

}

} else {

// the user has entered an email for whom the password reset link

// will be sent.

try {

const response = await ThirdPartyEmailPassword.sendPasswordResetEmail({

formFields: [

{

id: "email",

value: this.email,

},

],

});

if (response.status !== "OK") {

// this means that the email validation logic failed.

throw new Error(response.formFields[0].error);

}

// a password reset email was sent successfully.

if (this.didSubmit !== true) {

// we change the UI to show that the email has been sent

this.didSubmit = true;

}

} catch (e: any) {

this.errorMessage = e.message;

this.error = true;

}

}

},

},

});

</script>

如果该submitNewPassword功能成功,则表示用户密码已成功重置,我们将用户重定向回该/auth页面,以便他们现在可以使用新密码登录。

ForgotPassword要在 route 上加载组件/auth/reset-password,我们将在/src/router/index.ts文件中进行以下更改:

const router = createRouter({

history: createWebHistory(import.meta.env.BASE_URL),

routes: [

// ...

{

path: "/auth/reset-password",

name: "resetPassword",

component: () => ForgotPasswordView,

},

],

});

完成此操作后,如果您现在访问site,您应该会看到以下页面:

忘记密码输入邮箱

如果您输入您的电子邮件并按“给我发送电子邮件”按钮,您应该会在输入的电子邮件中收到一个重置密码的链接:

重置密码链接收件箱

点击链接后,您可以输入新密码并点击“更改密码”按钮更新密码:

重设密码

SuperTokens 核心设置

在进行后端设置时,我们将";其connectionURI用作核心。这是一个由 SuperTokens 团队托管的演示核心实例。您可以随意使用它,但是当您致力于使用 SuperTokens 时,您应该切换到核心的自托管或托管版本。

结论

我们使用supertokens-web-jsSDK 为 Vue 应用程序添加电子邮件密码、社交身份验证和忘记密码功能。

标签: #div填充20px #vuejs登录验证