如何使用 GraphQL 进行 OAuth2 认证
OAuth2 是一种流行的认证机制,它为应用程序提供了一种方式,使得用户可以不必透露他们的密码,就可以授权给第三方应用程序访问他们的资源。GraphQL 是一种流行的查询语言,它可以与任何后端语言和数据源一起使用。在这篇文章里,我们将介绍如何在前端使用 GraphQL 和 OAuth2 进行认证。
OAuth2 流程
OAuth2 协议包括四个角色:
Resource Owner (资源所有者) 代表了用户,拥有资源
Client (客户端) 代表了应用程序,需要访问资源
Authorization Server (授权服务器) 提供用于进行身份验证和授权的服务
Resource Server (资源服务器) 存储资源
下面是 OAuth2 的一些主要流程步骤:
Client 向 Authorization Server 发起请求,要求用户授权
Authorization Server 返回授权码给 Client
Client 使用授权码向 Authorization Server 发送请求,请求访问令牌
Authorization Server 返回访问令牌给 Client
Client 使用访问令牌向 Resource Server 发送请求,请求访问资源
Resource Server 返回资源给 Client
GraphQL 和 OAuth2
GraphQL 可以与 OAuth2 配合使用,以确保应用程序可以使用 GraphQL API,同时保护用户数据和隐私。
首先,客户端需要使用 GraphQL 查询授权服务器并请求授权码。这可以通过向 https://auth.server/authorize
发送 GET 请求来完成。如果用户在访问授权服务器时未经身份验证,会要求他们登录并授权应用程序。
query { authorizeCode(code: "123456", client_id: "myapp", redirect_uri: "https://myapp.com/callback") { access_token refresh_token expires_in } }
在此 GraphQL 查询中,我们提供了一个 code
,client_id
和 redirect_uri
参数。授权码是在用户成功授权后由授权服务器返回的,client_id
是我们在授权服务器注册的应用程序 ID,redirect_uri
是我们在授权服务器注册应用程序时使用的 URI。
一旦成功获得访问令牌,就可以使用 GraphQL 查询资源服务器并访问受保护的资源。
query { me { id name } }
在此 GraphQL 查询中,我们使用 access_token
向 Resource Server 发送身份验证请求。如果访问令牌无效,则 Resource Server 将返回错误。
示例代码
下面是一个示例应用程序,使用 Express 和 Apollo Server 搭建 GraphQL 服务器,在前端使用 React 和 Apollo Client,以演示如何使用 GraphQL 和 OAuth2 进行认证。这个示例应用程序将使用 GitHub OAuth2 登录授权。
- 安装依赖项
mkdir graphql-oauth2 cd graphql-oauth2 npm install --save express apollo-server-express babel-cli babel-preset-env babel-preset-stage-3 dotenv graphql graphql-tools
- 配置环境变量
在 .env
文件中添加以下环境变量,以配置 GitHub OAuth2 的 Client ID 和 Client Secret:
GITHUB_CLIENT_ID=client_id_here GITHUB_CLIENT_SECRET=client_secret_here
- 配置授权服务器
使用 Express 配置授权服务器:
-- -------------------- ---- ------- -- ----------------------- ------ ------- ---- ---------- ------ ----- ---- -------- ------ ----------- ---- -------------- ----- --- - ---------- ----------------- ----- ---- -- - ----- ------ - ----------------------- ---------- ----------------------------- ------------- --------------------------------- ------ ------- ------ ------------ --- ------------------------------------------------------------------- --- -------------------- ----- ----- ---- -- - ----- ---- - --------------- ----- ---- - - ---------- ----------------------------- -------------- --------------------------------- ---- -- ----- ------ - ---------------------------- ----- -------- - ----- -------------------------------------------------------------------- ----- ----- - ---------------------------------------------- ------------------------------------------------------ --- ---------------- -- -- -------------------------- ------ --------- -- ---- ---------
在这个授权服务器中,我们在路径 /login
上设置了一个重定向,它将用户重定向到 GitHub 授权页面。在授权页面上,用户可以选择授权应用程序访问他们的 GitHub 资源。
回调处理程序 /callback
将在用户授权成功后调用。它使用请求的授权码来交换访问令牌,并将其存储在 token
变量中。然后,它将用户重定向回我们的应用程序,将令牌作为查询参数传递。
- 配置资源服务器
使用 Apollo Server 配置资源服务器:
-- -------------------- ---- ------- -- ------------------ ------ - ------------- --- - ---- ------------------------ ------ - -------------------- - ---- ---------------- ------ ----- ---- -------- ----- -------- - ---- ---- ----- - --- ---- - ---- ---- - --- -- ------ ------ ----- ------ - -- ----- --------- - - ------ - --- ----- --- --- - ----- -- -- - ----- ------- - - -------------- ------- --------- -- ----- -------- - ----- ---------------------------------------- - ------- --- ------ - --- ----------------- ------ -------------------- ----- ------------------ -- - - -- ----- ------ - ---------------------- --------- --------- --- ----- ------ - --- -------------- ------- -------- -- --- -- -- -- ------ ------------------------- -- --- ------ ------- -------
在这个资源服务器中,我们定义了一个 GraphQL 查询 me
,它将使用 GitHub API 查询当前登录用户的个人信息。我们使用一个名为 token
的上下文参数来传递访问令牌。
- 开启服务器
使用以下命令,分别在两个终端窗口中分别启动授权服务器和资源服务器:
babel-node authorization-server.js
babel-node resource-server.js
在你的应用程序中,你可以使用 axios
或 Apollo Client
发送 GraphQL 查询,以获取受保护的资源,例如:
-- -------------------- ---- ------- ------ ------ - --------- --------- - ---- -------- ------ - --------------- ---- -------- - ---- ----------------- ------ - ------------- - ---- ------------------------ ------ - -------- - ---- ------------------- ------ ------------ ---- ---------------- ----- ----- - --- ---------------- ----- ---- - --- ---------- ---- -------------------------------- ------------ --------- --- ----- ------ - --- -------------- ------ ---- --- ----- -------- - ---- ----- - -- - -- ---- - - -- -------- ----- - ----- ------- --------- - --------------- ------------ -- - ----- ------ - --- ---------------------------------------- ----- - - -------------------- -- --- - ------------ ------------------------------- --- ----- - -- ---- ----- - ----- -------- ----- - - ------------------ - ----- ------- -------- - -------- - -------------- ------- --------- - - --- -- ------- ------ ------------------ -- --------- ------ ---------------------- ------ - ----- -------------- ------ -- - -------- ------ - ------ - --------------- ---------------- ---- -- ----------------- - - ------ ------- -----
在这个 React 应用程序中,我们使用 useEffect
钩子来解析 URL 查询参数,以获取 GitHub 访问令牌。我们使用 useQuery
钩子从 GraphQL API 中获取当前用户的姓名。
总结
掌握 OAuth2 和 GraphQL 可以帮助你创建一个安全、高效的 Web 应用程序。通过使用 OAuth2 认证,你可以使你的应用程序更安全,同时保护用户的隐私。使用 GraphQL,你可以以一种强大、可扩展、易于使用的方式访问数据。祝你好运,并且愉快的编程!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/651d0dbc95b1f8cacd491d97