Skip to main content

创建并添加自定义的用户与权限提供程序

🌐 Creating and adding a custom Users & Permissions provider

Strapi 提供了一个 内置提供者 列表,用于 用户与权限功能。你也可以按照本指南创建自己的提供者。

🌐 Strapi provides a list of built-in providers for the Users & Permissions feature. You can also create your own provider following this guide.

Prerequisites

你已经阅读了 用户与权限提供者文档 并理解了登录流程。

🌐 You have read the Users & Permissions providers documentation and understood the login flow.

创建自定义提供程序

🌐 Creating a custom provider

你可以使用 the register 生命周期函数 在 Strapi 应用的 src/index.js|ts 文件中创建你自己的自定义提供者。使用以下根据你的需求调整的代码示例:

🌐 You can use the register lifecycle function to create your own custom provider in the src/index.js|ts file of your Strapi application. Use the following code example adjusted to your needs:

/src/index.js
module.exports = {
register({ strapi }) {
strapi
.plugin("users-permissions")
.service("providers-registry")
.add("example-provider-name", {
icon: "",
enabled: true,
grantConfig: {
key: "",
secret: "",
callback: `${strapi.config.server.url}/auth/example-provider-name/callback`,
scope: ["email"],
authorize_url: "https://awesome.com/authorize",
access_url: "https://awesome.com/token",
oauth: 2,
},
async authCallback({ accessToken, providers, purest }) {
// use whatever you want here to get the user info
return {
username: "test",
email: "test",
};
},
});
},
};

有关传递给 grantConfig 的参数的更多信息,请参阅 `grant` 文档。有关 purest 的更多信息,请参阅 `purest` 文档

🌐 For additional information on parameters passed to grantConfig, please refer to the `grant` documentation. For additional information about purest please refer to `purest` documentation.

前端设置

🌐 Frontend setup

配置 Strapi 和提供程序后,你必须在前端应用中:

🌐 Once you have configured Strapi and the provider, in your frontend application you must:

  • 创建一个链接到 GET STRAPI_BACKEND_URL/api/connect/${provider} 的按钮(例如,https://strapi.mywebsite/api/connect/github)。
  • 创建一个前端路由,如 FRONTEND_URL/connect/${provider}/redirect,必须处理 access_token 参数,并且必须使用 access_token 参数请求 STRAPI_BACKEND_URL/api/auth/${provider}/callback
    JSON 请求响应将是 { "jwt": "...", "user": {...} }

现在你可以按照令牌使用中描述的方式进行身份验证请求。

🌐 Now you can make authenticated requests, as described in token usage.

Troubleshooting
  • 错误 429:这很可能是因为你的登录流程进入了循环。要向后端发起新的请求,你需要等待几分钟或重启后端。
  • Grant:缺少会话或提供程序配置错误:可能由于多种原因造成。
    • 无法构建重定向 URL:请确保已在 config/server.js 中设置后端 URL:设置服务器 URL
    • 会话/Cookie/缓存问题:你可以尝试在私密窗口中重新尝试。
    • 使用 ngrok 域名不正确:检查你的 URL,并确保使用 ngrok URL 而不是 http://localhost:1337。不要忘记检查示例应用中设置的后端 URL,位于 src/config.js
  • 你无法访问你的管理面板:最可能的原因是你使用 ngrok URL 设置了后端 URL 构建它,然后你停止/重新启动了 ngrok。你需要将后端 URL 替换为新的 ngrok URL,然后再次运行 yarn buildnpm run build

重置密码

🌐 Reset password

只能用于通过电子邮件提供商注册的用户。

假定的一般流程:

🌐 The assumed general flow:

  1. 用户访问你的忘记密码页面
  2. 用户输入他们的电子邮件地址。
  3. 你忘记密码的页面会向后端发送请求,以向用户发送包含重置密码链接的电子邮件。
  4. 用户收到电子邮件并单击特殊链接。
  5. 该链接会将用户重定向到你的重置密码页面
  6. 用户输入新密码。
  7. 重置密码页面 将新密码发送到后端。
  8. 如果请求包含步骤 3 链接中包含的代码,则密码将被更新。
  9. 用户可以使用新密码登录。

以下部分详细介绍了步骤 3 和 7。

🌐 The following section details steps 3 and 7.

🌐 Forgotten password: ask for the reset password link

此操作会向用户发送一封电子邮件,邮件中包含指向你的重置密码页面的链接。该链接将使用步骤7中重置密码所需的 URL 参数 code 进行增强。

🌐 This action sends an email to a user with the link to your reset password page. The link will be enriched with the url param code that is needed for the reset password at step 7.

首先,你必须指定以下内容:

🌐 First, you must specify the following:

  • 在管理面板:设置 > 用户与权限插件 > 高级设置 > 重置密码 页面,将 url 指向你的重置密码页面。
  • 在管理面板中:设置 > 用户与权限插件 > 电子邮件模板 页面,点击 发货人电子邮件

然后,你的忘记密码页面必须向你的后端发送以下请求:

🌐 Then, your forgotten password page has to make the following request to your backend:

import axios from 'axios';

// Request API.
axios
.post('http://localhost:1337/api/auth/forgot-password', {
email: 'user@strapi.io', // user's email
})
.then(response => {
console.log('Your user received an email');
})
.catch(error => {
console.log('An error occurred:', error.response);
});

重置密码:发送新密码

🌐 Reset Password: Send the new password

此操作将更新用户密码。 这同样适用于 GraphQL 插件,使用 resetPassword 变更。

🌐 This action will update the user password. This also works with the GraphQL Plugin, with the resetPassword mutation.

你的重置密码页面必须向你的后端发出以下请求:

🌐 Your reset password page has to make the following request to your backend:

import axios from 'axios';

// Request API.
axios
.post('http://localhost:1337/api/auth/reset-password', {
code: 'privateCode', // code contained in the reset link of step 3.
password: 'userNewPassword',
passwordConfirmation: 'userNewPassword',
})
.then(response => {
console.log("Your user's password has been reset.");
})
.catch(error => {
console.log('An error occurred:', error.response);
});

电子邮件验证

🌐 Email validation

Note

在生产环境中,确保已设置 url 配置属性。否则,验证链接将重定向到 localhost。关于该配置的更多信息请参见 这里

🌐 In production, make sure the url config property is set. Otherwise the validation link will redirect to localhost. More info on the config here.

注册后,如果你已将 启用电子邮件确认 设置为 开启,用户将通过电子邮件收到一个确认链接。用户必须点击该链接以验证他们的注册。

🌐 After registering, if you have set Enable email confirmation to ON, the user will receive a confirmation link by email. The user has to click on it to validate their registration.

确认链接示例:https://yourwebsite.com/api/auth/email-confirmation?confirmation=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaWF0IjoxNTk0OTgxMTE3LCJleHAiOjE1OTc1NzMxMTd9.0WeB-mvuguMyr4eY8CypTZDkunR--vZYzZH6h6sChFg

🌐 Example of the confirmation link: https://yourwebsite.com/api/auth/email-confirmation?confirmation=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaWF0IjoxNTk0OTgxMTE3LCJleHAiOjE1OTc1NzMxMTd9.0WeB-mvuguMyr4eY8CypTZDkunR--vZYzZH6h6sChFg

如果需要,你可以通过提出以下请求重新发送确认电子邮件:

🌐 If needed you can re-send the confirmation email by making the following request:

import axios from 'axios';

// Request API.
axios
.post(`http://localhost:1337/api/auth/send-email-confirmation`, {
email: 'user@strapi.io', // user's email
})
.then(response => {
console.log('Your user received an email');
})
.catch(error => {
console.error('An error occurred:', error.response);
});

向你的 Strapi 应用添加新提供者

🌐 Adding a new provider to your Strapi application

Info

本文件可能没有与 Strapi 5 保持最新,并且仍在进行中。同时, contributions 非常欢迎。

Grant 提供多个常用 OAuth 提供商的配置。 Custom 也支持提供商
你可以在此查看并试用 200 多个支持的提供商: OAuth Playground

准备好你的文件

🌐 Prepare your files

要在 Strapi 上添加新提供商,你需要对以下文件进行更改:

🌐 To add a new provider on Strapi, you will need to perform changes to the following files:

extensions/users-permissions/services/Providers.js
extensions/users-permissions/config/functions/bootstrap.js

如果这些文件不存在,你需要从你的 node_modules 或 Strapi 单仓库中复制。你可以查看 插件扩展 以获取关于其工作原理的更多信息。

🌐 If these files don't exist you will need to copy from your node_modules or the Strapi mono-repo. You can see plugin extensions for more information on how it works.

我们将一步一步进行。

🌐 We will go step by step.

配置你的提供者请求

🌐 Configure your provider request

Provider.js 文件的 getProfile 函数中配置新的提供程序。

🌐 Configure the new provider in the Provider.js file at the getProfile function.

getProfile 接受三个参数:

🌐 The getProfile takes three params:

  • 提供者:所使用提供者的名称,字符串形式。
  • 查询:查询是提供者回调的结果。
  • 回调:将继续内部 Strapi 登录逻辑的回调函数。

这里是一个使用 discord 提供程序的例子。

🌐 Here is an example that uses the discord provider.

配置你的 OAuth 通用信息

🌐 Configure your OAuth generic information

case 'discord': {
const discord = new Purest({
provider: 'discord',
config: {
'discord': {
'https://discordapp.com/api/': {
'__domain': {
'auth': {
'auth': {'bearer': '[0]'}
}
},
'{endpoint}': {
'__path': {
'alias': '__default'
}
}
}
}
}
});
}

这段代码创建了一个 Purest 对象,它为我们提供了一种与提供商的 REST API 交互的通用方式。

🌐 This code creates a Purest object that gives us a generic way to interact with the provider's REST API.

有关使用 Purest 模块的更多规范,请参阅 Official Purest Documentation

你可能还想看看已经制作好的众多配置 here

获取你的用户信息

🌐 Retrieve your user's information

对于我们的 Discord 提供商,它将如下所示:

🌐 For our Discord provider it will look like the following:

  discord.query().get('users/@me').auth(access_token).request((err, res, body) => {
if (err) {
callback(err);
} else {
// Combine username and discriminator because discord username is not unique
const username = `${body.username}#${body.discriminator}`;
callback(null, {
username,
email: body.email
});
}
});
break;
}

这是我们开关的下一部分。既然我们已经正确配置了我们的提供者,我们就想用它来获取用户信息。

🌐 Here is the next part of our switch. Now that we have properly configured our provider, we want to use it to retrieve user information.

在这里,你可以看到 purest 的真正威力,你只需在所需的 URL 上发起一个 GET 请求,使用 query 参数中的 access_token 进行认证。

🌐 Here you see the real power of purest, you can simply make a get request on the desired URL, using the access_token from the query parameter to authenticate.

这样,你应该能够检索所需的用户信息。

🌐 That way, you should be able to retrieve the user info you need.

现在,你可以简单地使用用户的用户名和邮箱调用 callback 函数。这样,Strapi 将能够从数据库中检索你的用户并登录。

🌐 Now, you can simply call the callback function with the username and email of your user. That way, Strapi will be able to retrieve your user from the database and log you in.

将新的提供者模型配置到数据库上

🌐 Configure the new provider model onto database

现在,我们需要为我们的新提供商配置‘模型’。这样,我们的设置就可以存储在数据库中,并从管理面板进行管理。

🌐 Now, we need to configure our 'model' for our new provider. That way, our settings can be stored in the database, and managed from the admin panel.

打开文件 packages/strapi-plugin-users-permissions/config/functions/bootstrap.js

🌐 Open the file packages/strapi-plugin-users-permissions/config/functions/bootstrap.js

将你的提供商所需的字段添加到 grantConfig 对象中。 对于我们的 Discord 提供商,它将如下所示:

🌐 Add the fields your provider needs into the grantConfig object. For our discord provider it will look like:

discord: {
enabled: false, // make this provider disabled by default
icon: 'comments', // The icon to use on the UI
key: '', // our provider app id (leave it blank, you will fill it with the Content Manager)
secret: '', // our provider secret key (leave it blank, you will fill it with the Content Manager)
callback: '/auth/discord/callback', // the callback endpoint of our provider
scope: [ // the scope that we need from our user to retrieve information
'identify',
'email'
]
},