搜索
首页web前端js教程您的水疗中心的社交登录:通过Google和Facebook来验证您的用户

Social Login for Your SPA: Authenticate Your Users via Google and Facebook

Social Login for Your SPA: Authenticate Your Users via Google and Facebook

单页应用架构的Web应用日益增多,这类应用将整个应用作为JavaScript加载到浏览器中,所有与服务器的交互都通过返回JSON文档的基于HTTP的API进行。这些应用通常需要某种程度的用户限制交互,例如存储用户个人资料详细信息。在传统的基于HTML的应用中实现这一功能相对简单,但在需要对每个API请求进行身份验证的单页应用中,则更为棘手。

本文将演示一种使用Passport.js库实现多种提供商的社交登录,并由此实现后续API调用的基于令牌的身份验证的技术。

本文的所有源代码均可从我们的GitHub存储库下载。

关键要点

  • 使用Passport.js库实现Google和Facebook的社交登录,增强单页应用的用户身份验证。
  • 选择JSON Web Tokens (JWT)进行安全的基于令牌的API身份验证,避免基于会话和cookie的限制。
  • 利用社交登录功能:简化的UI,无需存储用户凭据,以及跨站点密码重置功能。
  • 使用passport-google-oauth、passport-facebook和passport-jwt等特定模块配置Passport,以管理身份验证和令牌生成。
  • 使用passport-jwt模块实现基于令牌的身份验证,通过验证Authorization标头中的JWT来保护API端点。
  • 通过重定向模式和客户端脚本处理社交登录身份验证和令牌分发,简化用户体验。

为什么在您的SPA中使用社交登录?

在您的Web应用中实现登录机制时,需要考虑许多问题。

  • 您的UI应该如何处理身份验证本身?
  • 您应该如何存储用户信息?
  • 您应该如何最好地保护用户凭据?

在开始编写登录门户之前,需要考虑这些以及更多问题。但是,有一种更好的方法。

许多网站,主要是社交网络,允许您使用它们的平台来验证您自己的应用。这是通过许多不同的API实现的——OAuth 1.0、OAuth 2.0、OpenID、OpenID Connect等。

通过使用这些社交登录技术来实现您的登录流程,可以提供许多优势。

  • 您不再负责呈现用户用来进行身份验证的UI。
  • 您不再负责存储和保护敏感的用户详细信息。
  • 用户能够使用单个登录来访问多个站点。
  • 如果用户觉得他们的密码已被泄露,他们可以重置一次密码,并在许多站点中受益。
  • 通常,提供身份验证功能的服务将提供其他详细信息。例如,这可以用于自动注册从未使用过您网站的用户,或者允许您代表他们发布更新到他们的个人资料。

为什么对您的API使用基于令牌的身份验证?

每当客户端需要访问您的API时,您都需要某种方法来确定它们是谁以及是否允许访问。实现此目标的方法有很多,但主要选项是:

  • 基于会话的身份验证
  • 基于cookie的身份验证
  • 基于令牌的身份验证

基于会话的身份验证需要您的API服务能够将会话与客户端关联起来。这通常非常容易设置,但是如果您在多个服务器上部署您的API,则可能会出现问题。您也受服务器用于会话管理和过期的机制的限制,这可能不受您的控制。

基于cookie的方法是,您只需在cookie中存储一些标识符,这将用于自动识别API请求。这意味着您首先需要某种设置cookie的机制,并且您有可能会在后续请求中泄露它,因为cookie会自动包含在对同一主机的所有(合适的)请求中。

基于令牌的方法是基于cookie的身份验证的一种变体,但它可以让您更多地控制。本质上,您生成令牌的方式与基于cookie的身份验证系统相同,但是您将自己包含在请求中——通常在“Authorization”标头中或直接在URL中。这意味着您可以完全控制存储令牌、哪些请求将包含它等等。

注意:即使HTTP标头称为“Authorization”,我们实际上也在使用它进行身份验证。这是因为我们正在使用它来确定客户端“是谁”,而不是客户端“被允许做什么”。

用于生成令牌的策略也很重要。这些令牌可以是引用令牌,这意味着它们只不过是服务器用来查找真实详细信息的标识符。或者完整的令牌,这意味着令牌已经包含了所有必要的信息。

引用令牌具有显著的安全优势,因为绝对不会向客户端泄露用户凭据。但是,由于您需要在每次发出的请求中将令牌解析为实际凭据,因此会产生性能损失。

完整令牌则相反。它们会将用户凭据暴露给任何能够理解令牌的人,但是由于令牌是完整的,因此在查找它时不会产生性能损失。

通常,完整令牌将使用JSON Web Tokens标准来实现,因为该标准允许改进令牌的安全性。具体来说,JWT允许对令牌进行加密签名,这意味着您可以保证令牌没有被篡改。还规定可以对它们进行加密,这意味着如果没有加密密钥,甚至无法解码令牌。

如果您想回顾一下在Node中使用JWT,请查看我们的教程:使用JSON Web Tokens与Node.js。

使用完整令牌的另一个缺点是大小。例如,引用令牌可以使用UUID来实现,其长度为36个字符。相反,JWT很容易长达数百个字符。

在本文中,我们将使用JWT令牌来演示它们如何工作。但是,当您自己实现此功能时,您需要决定是否要使用引用令牌或完整令牌,以及将为此使用什么机制。

什么是Passport?

Passport是Node.js的一组模块,用于在您的Web应用中实现身份验证。它可以非常轻松地插入许多基于Node的Web服务器,并使用模块化结构来实现您需要的登录机制,而不会产生过多的膨胀。

Passport是一个功能强大的模块套件,涵盖了大量的身份验证需求。使用这些模块,我们可以创建一个可插入的设置,允许为不同的端点提供不同的身份验证需求。所使用的身份验证系统可以像简单地检查URL中的特殊值一样简单,也可以像依赖第三方提供商来完成所有工作一样复杂。

在本文中,我们将使用passport-google-oauth、passport-facebook和passport-jwt模块,以便为API端点实现社交登录和基于JWT令牌的身份验证。

passport-jwt模块将用于要求某些端点——我们实际需要身份验证才能访问的API端点——在请求中必须存在有效的JWT。passport-google-oauth和passport-facebook模块将用于提供分别针对Google和Facebook进行身份验证的端点,然后生成可用于访问应用中其他端点的JWT。

为您的单页应用实现社交登录

从这里开始,我们将逐步介绍如何获取一个简单的单页应用并为其实现社交登录。此应用使用Express编写,一个简单的API提供一个安全端点和一个不安全端点。如果您想继续操作,可以从https://github.com/sitepoint-editors/social-logins-spa检出此应用的源代码。可以通过在下载的源代码中执行npm install来构建此应用——下载所有依赖项——然后通过执行node src/index.js来运行。

为了成功使用该应用,您需要在Google和Facebook注册社交登录凭据,并将凭据提供给该应用。完整的说明可在演示应用的README文件中找到。这些凭据作为环境变量访问。因此,应用可以按如下方式运行:

# Linux / OS X
$ export GOOGLE_CLIENTID=myGoogleClientId
$ export GOOGLE_CLIENTSECRET=myGoogleClientSecret
$ export FACEBOOK_CLIENTID=myFacebookClientId
$ export FACEBOOK_CLIENTSECRET=myFacebookClientSecret
$ node src/index.js
# Windows
> set GOOGLE_CLIENTID=myGoogleClientId
> set GOOGLE_CLIENTSECRET=myGoogleClientSecret
> set FACEBOOK_CLIENTID=myFacebookClientId
> set FACEBOOK_CLIENTSECRET=myFacebookClientSecret
> node src/index.js

此过程的最终结果是将令牌身份验证支持(使用JSON Web Tokens)添加到我们的安全端点,然后添加社交登录支持(使用Google和Facebook)以获取令牌供应用的其余部分使用。这意味着您需要使用社交提供商进行一次身份验证,然后使用生成的JWT进行应用中所有未来的API调用。

JWT对于我们的场景来说是一个特别好的选择,因为它们是完全自包含的,同时仍然是安全的。JWT由JSON有效负载和加密签名组成。有效负载包含已认证用户的详细信息、认证系统和令牌的有效期。然后,签名确保恶意第三方无法伪造它——只有拥有签名密钥的人才能生成令牌。

在阅读本文时,您会经常看到对作为应用一部分包含的config.js模块的引用。此模块用于配置应用,并使用Node-convict模块进行外部配置。本文中使用的配置如下:

  • http.port – 应用运行的端口。默认为3000,并使用“PORT”环境变量覆盖。
  • authentication.google.clientId – 用于Google身份验证的Google客户端ID。这通过“GOOGLE_CLIENTID”环境变量提供给应用。
  • authentication.google.clientSecret – 用于Google身份验证的Google客户端密钥。这通过“GOOGLE_CLIENTSECRET”环境变量提供给应用。
  • authentication.facebook.clientId – 用于Facebook身份验证的Facebook客户端ID。这通过“FACEBOOK_CLIENTID”环境变量提供给应用。
  • authentication.facebook.clientSecret – 用于Facebook身份验证的Facebook客户端密钥。这通过“FACEBOOK_CLIENTSECRET”环境变量提供给应用。
  • authentication.token.secret – 用于签署我们身份验证令牌的JWT的密钥。默认为“mySuperSecretKey”。
  • authentication.token.issuer – JWT中存储的发行者。这表示哪个服务发出了令牌,在一种身份验证服务为许多应用提供服务的情况下。
  • authentication.token.audience – JWT中存储的受众。这表示令牌的目标服务,在一种身份验证服务为许多应用提供服务的情况下。

集成Passport

在您的应用中使用Passport之前,需要进行少量设置。这只不过是确保模块已安装,并在您的Express应用中初始化中间件。

此阶段所需的模块是passport模块,然后要设置中间件,我们只需将其添加到我们的Express应用中即可。

// src/index.js
const passport = require('passport');
.....
app.use(passport.initialize());

如果您遵循Passport网站上的说明,则会让您设置会话支持——通过使用passport.session()调用。我们在应用中不使用任何会话支持,因此这是不必要的。这是因为我们正在实现一个无状态API,因此我们将对每个请求提供身份验证,而不是将其持久化到会话中。

为安全端点实现JWT令牌身份验证

使用Passport设置JWT令牌身份验证相对简单。我们将使用passport-jwt模块,它将为我们完成所有繁重的工作。此模块查找值为“JWT ”开头的“Authorization”标头,并将标头的其余部分视为用于身份验证的JWT令牌。然后,它解码JWT并将其中存储的值提供给您自己的代码进行操作——例如,执行用户查找。如果JWT无效,例如签名无效、令牌已过期……则请求将未经身份验证,而无需您自己的代码额外参与。

然后,配置JWT令牌身份验证的方法如下:

# Linux / OS X
$ export GOOGLE_CLIENTID=myGoogleClientId
$ export GOOGLE_CLIENTSECRET=myGoogleClientSecret
$ export FACEBOOK_CLIENTID=myFacebookClientId
$ export FACEBOOK_CLIENTSECRET=myFacebookClientSecret
$ node src/index.js

在上面,我们使用了一些内部模块:

  • config.js – 包含我们整个应用的配置属性。可以假设这些属性已经配置好,并且值可以随时使用。
  • users.js – 这是应用的用户存储。这允许加载和创建用户——在这里,我们只是按其内部ID加载用户。

在这里,我们使用已知的密钥、发行者和受众配置JWT解码器,并且我们告知策略它应该从Authorization标头获取JWT。如果发行者或受众中的任何一个与JWT中存储的内容不匹配,则身份验证将失败。这为我们提供了另一层防伪造保护,尽管这是一个非常简单的保护。

令牌解码完全由passport-jwt模块处理,我们只需要提供与最初用于生成令牌的配置相对应的配置即可。因为JWT是一个标准,所以任何遵循该标准的模块都能完美地协同工作。

成功解码令牌后,它将作为有效负载传递给我们的回调。在这里,我们只是尝试查找由令牌中的“主题”标识的用户。实际上,您可能会进行额外的检查,例如确保令牌未被吊销。

如果找到用户,我们将其提供给Passport,然后Passport将其提供给请求处理的其余部分作为req.user。如果找不到用户,则我们不向Passport提供任何用户,然后Passport将认为身份验证失败。

这现在可以连接到请求处理程序,以便请求需要身份验证才能成功:

# Windows
> set GOOGLE_CLIENTID=myGoogleClientId
> set GOOGLE_CLIENTSECRET=myGoogleClientSecret
> set FACEBOOK_CLIENTID=myFacebookClientId
> set FACEBOOK_CLIENTSECRET=myFacebookClientSecret
> node src/index.js

上面第3行是使Passport处理请求的魔法。这会导致Passport在我们传入的请求上运行我们刚刚配置的“jwt”策略,并允许其继续进行或立即失败。

我们可以通过运行应用——通过执行node src/index.js——并尝试访问此资源来查看其运行情况:

// src/index.js
const passport = require('passport');
.....
app.use(passport.initialize());

我们没有提供任何Authorization标头,它不允许我们继续进行。但是,如果您提供有效的Authorization标头,您将获得成功的响应:

// src/authentication/jwt.js
const passport = require('passport');
const passportJwt = require('passport-jwt');
const config = require('../config');
const users = require('../users');

const jwtOptions = {
  // 从 "Authorization" 标头获取 JWT。
  // 默认情况下,这会查找 "JWT " 前缀
  jwtFromRequest: passportJwt.ExtractJwt.fromAuthHeader(),
  // 用于签署 JWT 的密钥
  secretOrKey: config.get('authentication.token.secret'),
  // JWT 中存储的发行者
  issuer: config.get('authentication.token.issuer'),
  // JWT 中存储的受众
  audience: config.get('authentication.token.audience')
};

passport.use(new passportJwt.Strategy(jwtOptions, (payload, done) => {
  const user = users.getUserById(parseInt(payload.sub));
  if (user) {
      return done(null, user, payload);
  }
  return done();
}));

为了执行此测试,我通过访问https://www.jsonwebtoken.io并填写那里的表单手动生成了一个JWT。“有效负载”是我使用的:

// src/index.js
app.get('/api/secure',
  // 此请求必须使用 JWT 进行身份验证,否则我们将失败
  passport.authenticate(['jwt'], { session: false }),
  (req, res) => {
    res.send('Secure response from ' + JSON.stringify(req.user));
  }
);

“签名密钥”是“mySuperSecretKey”,取自配置。

支持令牌生成

现在我们可以只使用有效令牌访问资源了,我们需要一种实际生成令牌的方法。这是使用jsonwebtoken模块完成的,它构建了一个包含正确详细信息并使用与上面相同的密钥签名的JWT。

# Linux / OS X
$ export GOOGLE_CLIENTID=myGoogleClientId
$ export GOOGLE_CLIENTSECRET=myGoogleClientSecret
$ export FACEBOOK_CLIENTID=myFacebookClientId
$ export FACEBOOK_CLIENTSECRET=myFacebookClientSecret
$ node src/index.js

请注意,我们在生成JWT时使用完全相同的受众、发行者和密钥配置设置。我们还指定JWT的有效期为一小时。这可以是您认为对您的应用来说合理的任何时间段,甚至可以从配置中提取,以便可以轻松更改。

在这种情况下,没有指定JWT ID,但这可以用来为令牌生成一个完全唯一的ID——例如使用UUID。然后,这为您提供了一种吊销令牌的方法,并在数据存储中存储吊销ID的集合,并在处理Passport策略中的JWT时检查JWT ID是否不在列表中。

社交登录提供商

现在我们有能力生成令牌了,我们需要一种让用户实际登录的方法。这就是社交登录提供商发挥作用的地方。我们将添加一项功能,让用户重定向到社交登录提供商,并在成功后生成JWT令牌并将其提供给浏览器的JavaScript引擎以供将来请求使用。我们已经具备了几乎所有这方面的组件,我们只需要将它们组合在一起即可。

Passport中的社交登录提供商分为两部分。首先,需要使用适当的插件实际为社交登录提供商配置Passport。其次,需要用户被定向到的Express路由才能启动身份验证,以及用户在身份验证成功后被重定向到的路由。

我们将在新的子浏览器窗口中打开这些URL,我们可以在完成后关闭这些窗口,并且能够调用打开它的窗口内的JavaScript方法。这意味着该过程对于用户来说相对透明——最多他们会看到一个新的窗口打开,要求他们提供凭据,但最好他们除了现在已登录的事实外什么也看不到。

此浏览器的方面需要由两部分组成。弹出窗口的视图以及在主窗口中处理此视图的JavaScript。这可以很容易地与任何框架集成,但在此示例中,我们将为了简单起见使用vanilla JavaScript。

主页面JavaScript只需要类似这样的内容:

# Windows
> set GOOGLE_CLIENTID=myGoogleClientId
> set GOOGLE_CLIENTSECRET=myGoogleClientSecret
> set FACEBOOK_CLIENTID=myFacebookClientId
> set FACEBOOK_CLIENTSECRET=myFacebookClientSecret
> node src/index.js

这在窗口上注册一个全局函数对象(名为authenticateCallback),它将存储访问令牌,然后打开我们的路由以启动身份验证,我们正在访问/api/authentication/{provider}/start。

然后,可以使用您希望启动身份验证的任何方式触发此函数。这通常是标题区域中的登录链接,但详细信息完全取决于您的应用。

第二部分是在成功身份验证后要呈现的视图。在这种情况下,我们为了简单起见使用Mustache,但这将使用对您来说最合适的任何视图技术。

# Linux / OS X
$ export GOOGLE_CLIENTID=myGoogleClientId
$ export GOOGLE_CLIENTSECRET=myGoogleClientSecret
$ export FACEBOOK_CLIENTID=myFacebookClientId
$ export FACEBOOK_CLIENTSECRET=myFacebookClientSecret
$ node src/index.js

在这里,我们只有一个简单的JavaScript代码,它在该窗口的打开程序(即主应用窗口)上调用上面的authenticateCallback方法,然后我们关闭自己。

此时,JWT令牌将在主应用窗口中可用,用于您想要的任何目的。

实现Google身份验证

使用passport-google-oauth模块将针对Google进行身份验证。这需要提供三条信息:

  • 客户端ID
  • 客户端密钥
  • 重定向URL

客户端ID和密钥是通过在Google开发者控制台中注册您的应用获得的。重定向URL是用户在使用其Google凭据登录后将被发送回您的应用中的URL。这将取决于应用的部署方式和位置,但现在我们将对其进行硬编码。

然后,我们的Google身份验证Passport配置将如下所示:

# Windows
> set GOOGLE_CLIENTID=myGoogleClientId
> set GOOGLE_CLIENTSECRET=myGoogleClientSecret
> set FACEBOOK_CLIENTID=myFacebookClientId
> set FACEBOOK_CLIENTSECRET=myFacebookClientSecret
> node src/index.js

当用户在成功身份验证后重定向回我们时,我们会得到他们在Google系统中的ID和一些个人资料信息。我们首先尝试查看此用户是否以前登录过。如果是,那么我们获取他们的用户记录,我们就完成了。如果不是,我们将为他们注册一个新帐户,然后我们将使用这个新帐户。这为我们提供了一种透明的机制,用户注册在第一次登录时完成。如果需要,我们可以以不同的方式进行此操作,但现在没有必要。

接下来是设置路由处理程序以管理此登录。这些将如下所示:

// src/index.js
const passport = require('passport');
.....
app.use(passport.initialize());

请注意/api/authentication/google/start和/api/authentication/gogle/redirect的路由。如上所述,/start变体是我们打开的URL,/redirect变体是Google在成功时将用户重定向到的URL。然后,这将呈现我们上面显示的已认证视图,提供生成的JWT供其使用。

实现Facebook身份验证

现在我们有了第一个社交登录提供商,让我们扩展并添加第二个。这次将是Facebook,使用passport-facebook模块。

此模块的工作方式与Google模块几乎相同,需要相同的配置和相同的设置。唯一的真正区别在于它是不同的模块,并且访问它的URL结构不同。

为了配置Facebook身份验证,您还需要客户端ID、客户端密钥和重定向URL。客户端ID和客户端密钥(Facebook称为应用ID和应用密钥)可以通过在Facebook开发者控制台中创建Facebook应用获得。您需要确保将“Facebook登录”产品添加到您的应用中才能使其正常工作。

我们的Facebook身份验证Passport配置将是:

// src/authentication/jwt.js
const passport = require('passport');
const passportJwt = require('passport-jwt');
const config = require('../config');
const users = require('../users');

const jwtOptions = {
  // 从 "Authorization" 标头获取 JWT。
  // 默认情况下,这会查找 "JWT " 前缀
  jwtFromRequest: passportJwt.ExtractJwt.fromAuthHeader(),
  // 用于签署 JWT 的密钥
  secretOrKey: config.get('authentication.token.secret'),
  // JWT 中存储的发行者
  issuer: config.get('authentication.token.issuer'),
  // JWT 中存储的受众
  audience: config.get('authentication.token.audience')
};

passport.use(new passportJwt.Strategy(jwtOptions, (payload, done) => {
  const user = users.getUserById(parseInt(payload.sub));
  if (user) {
      return done(null, user, payload);
  }
  return done();
}));

这与Google的配置几乎相同,只是使用了“facebook”而不是“google”。URL路由也类似:

// src/index.js
app.get('/api/secure',
  // 此请求必须使用 JWT 进行身份验证,否则我们将失败
  passport.authenticate(['jwt'], { session: false }),
  (req, res) => {
    res.send('Secure response from ' + JSON.stringify(req.user));
  }
);

在这里,我们不需要指定我们要使用的范围,因为默认集已经足够好。否则,Google和Facebook之间的配置几乎相同。

总结

使用社交登录提供商可以快速轻松地将用户登录和注册添加到您的应用中。事实上,这使用浏览器重定向将用户发送到社交登录提供商,然后发送回您的应用,这使得将其集成到单页应用中可能会很棘手,即使将其集成到更传统的应用中相对容易。

本文展示了一种将这些社交登录提供商集成到单页应用中的方法,这种方法有望既易于使用,又易于扩展到您可能希望使用的未来提供商。Passport有很多模块可以与不同的提供商一起工作,这只是找到合适的模块并像我们上面对Google和Facebook所做的那样对其进行配置的问题。

本文由James Kolce进行同行评审。感谢所有SitePoint的同行评审人员,使SitePoint内容达到最佳状态

关于社交登录集成的常见问题解答 (FAQs)

将社交登录集成到我的Web应用中有哪些好处?

将社交登录集成到您的Web应用中可以带来多项好处。首先,它简化了用户的注册流程,因为他们可以使用现有的社交媒体帐户注册,无需记住另一个用户名和密码。其次,它可以提高转化率,因为简化的注册流程可以鼓励更多用户注册。最后,它可以让您访问其社交媒体个人资料中的用户数据,这些数据可用于个性化他们在您网站上的体验。

使用社交登录时,如何确保用户数据的安全?

在集成社交登录时,确保用户数据的安全至关重要。您可以通过使用安全的协议(如OAuth 2.0)进行身份验证来实现这一点,这确保用户密码不会与您的应用共享。此外,您应该只请求应用所需的最小数量的用户数据,并确保安全地存储这些数据。

我可以在我的Web应用中集成多个社交登录吗?

是的,您可以在您的Web应用中集成多个社交登录。这可以为用户提供更多选择,并增加他们注册的可能性。但是,重要的是要确保无论用户选择使用哪个社交登录,用户体验都能保持无缝衔接。

如何处理拥有多个社交媒体帐户的用户?

处理拥有多个社交媒体帐户的用户可能具有挑战性。一种解决方案是允许用户将多个社交媒体帐户链接到您的应用上的单个帐户。这样,他们可以选择使用任何已链接的帐户登录。

如果用户停用其社交媒体帐户会发生什么?

如果用户停用其社交媒体帐户,他们将无法再使用该帐户登录您的应用。为了处理这种情况,您可以为用户提供添加电子邮件地址或电话号码到其帐户的选项,如果他们停用其社交媒体帐户,则可以使用这些信息登录。

如何自定义社交登录按钮的外观?

可以使用CSS自定义社交登录按钮的外观。但是,务必遵守社交媒体平台提供的品牌指南。例如,Facebook的“f”徽标应始终以其原始形式使用,并且不应以任何方式修改。

我可以将社交登录用于移动应用吗?

是的,社交登录可用于Web和移动应用。在移动应用中集成社交登录的过程与Web应用类似,但您可能需要使用社交媒体平台提供的特定SDK。

如何测试社交登录功能?

您可以通过在社交媒体平台上创建测试帐户并使用这些帐户登录您的应用来测试社交登录功能。这可以帮助您在应用启动之前识别任何问题或错误。

如果用户忘记使用哪个社交媒体帐户注册,我该怎么办?

如果用户忘记使用哪个社交媒体帐户注册,您可以提供一个恢复选项,让他们可以输入其电子邮件地址或电话号码以接收与其帐户链接的社交媒体帐户列表。

我可以在不进行编码的情况下集成社交登录吗?

虽然可以使用某些工具和插件在不进行编码的情况下集成社交登录,但了解一些编码知识会很有益。这可以为您提供更多灵活性和对集成过程的控制,还可以帮助您解决可能出现的任何问题。

以上是您的水疗中心的社交登录:通过Google和Facebook来验证您的用户的详细内容。更多信息请关注PHP中文网其他相关文章!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
在JavaScript中替换字符串字符在JavaScript中替换字符串字符Mar 11, 2025 am 12:07 AM

JavaScript字符串替换方法详解及常见问题解答 本文将探讨两种在JavaScript中替换字符串字符的方法:在JavaScript代码内部替换和在网页HTML内部替换。 在JavaScript代码内部替换字符串 最直接的方法是使用replace()方法: str = str.replace("find","replace"); 该方法仅替换第一个匹配项。要替换所有匹配项,需使用正则表达式并添加全局标志g: str = str.replace(/fi

构建您自己的Ajax Web应用程序构建您自己的Ajax Web应用程序Mar 09, 2025 am 12:11 AM

因此,在这里,您准备好了解所有称为Ajax的东西。但是,到底是什么? AJAX一词是指用于创建动态,交互式Web内容的一系列宽松的技术。 Ajax一词,最初由Jesse J创造

10个JQuery Fun and Games插件10个JQuery Fun and Games插件Mar 08, 2025 am 12:42 AM

10款趣味横生的jQuery游戏插件,让您的网站更具吸引力,提升用户粘性!虽然Flash仍然是开发休闲网页游戏的最佳软件,但jQuery也能创造出令人惊喜的效果,虽然无法与纯动作Flash游戏媲美,但在某些情况下,您也能在浏览器中获得意想不到的乐趣。 jQuery井字棋游戏 游戏编程的“Hello world”,现在有了jQuery版本。 源码 jQuery疯狂填词游戏 这是一个填空游戏,由于不知道单词的上下文,可能会产生一些古怪的结果。 源码 jQuery扫雷游戏

jQuery视差教程 - 动画标题背景jQuery视差教程 - 动画标题背景Mar 08, 2025 am 12:39 AM

本教程演示了如何使用jQuery创建迷人的视差背景效果。 我们将构建一个带有分层图像的标题横幅,从而创造出令人惊叹的视觉深度。 更新的插件可与JQuery 1.6.4及更高版本一起使用。 下载

如何创建和发布自己的JavaScript库?如何创建和发布自己的JavaScript库?Mar 18, 2025 pm 03:12 PM

文章讨论了创建,发布和维护JavaScript库,专注于计划,开发,测试,文档和促销策略。

如何在浏览器中优化JavaScript代码以进行性能?如何在浏览器中优化JavaScript代码以进行性能?Mar 18, 2025 pm 03:14 PM

本文讨论了在浏览器中优化JavaScript性能的策略,重点是减少执行时间并最大程度地减少对页面负载速度的影响。

使用jQuery和Ajax自动刷新DIV内容使用jQuery和Ajax自动刷新DIV内容Mar 08, 2025 am 12:58 AM

本文演示了如何使用jQuery和ajax自动每5秒自动刷新DIV的内容。 该示例从RSS提要中获取并显示了最新的博客文章以及最后的刷新时间戳。 加载图像是选择

Matter.js入门:简介Matter.js入门:简介Mar 08, 2025 am 12:53 AM

Matter.js是一个用JavaScript编写的2D刚体物理引擎。此库可以帮助您轻松地在浏览器中模拟2D物理。它提供了许多功能,例如创建刚体并为其分配质量、面积或密度等物理属性的能力。您还可以模拟不同类型的碰撞和力,例如重力摩擦力。 Matter.js支持所有主流浏览器。此外,它也适用于移动设备,因为它可以检测触摸并具有响应能力。所有这些功能都使其值得您投入时间学习如何使用该引擎,因为这样您就可以轻松创建基于物理的2D游戏或模拟。在本教程中,我将介绍此库的基础知识,包括其安装和用法,并提供一

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
3 周前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
3 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Atom编辑器mac版下载

Atom编辑器mac版下载

最流行的的开源编辑器

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。

VSCode Windows 64位 下载

VSCode Windows 64位 下载

微软推出的免费、功能强大的一款IDE编辑器

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。