北京网站建设公司拟,做排行网站,网站建设相关网站,咸阳机场建设招聘信息网站“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕#xff1f; 尝试使用Okta API进行托管身份验证#xff0c;授权和多因素身份验证。 GraphQL是Facebook在2012年开发的一种数据查询语言#xff0c;用于解决REST API和传… “我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕 尝试使用Okta API进行托管身份验证授权和多因素身份验证。 GraphQL是Facebook在2012年开发的一种数据查询语言用于解决REST API和传统数据库模型的缺点。 通常当程序员编写REST API数据查询时他们默认只在需要一部分数据时才检索整个数据结构。 例如如果您要查找博客文章中的评论数开发人员通常可能会检索整个文章和所有关联的字段以及所有评论及其所有关联字段 只是为了计算结果中的评论数数组。 这是非常低效的。 但是现代计算机速度很快。 只要您有成百上千的用户这些天甚至是共享服务器都非常快。 但是当您达到Facebook规模在互联网上接触到相当多的人时这种情况就会崩溃。 这种低效率变得不可行或昂贵。 当然可以编写更好的SQL查询或NoSQL查询并编写特定的API前端调用来计算效率更高的博客文章数量-但是您必须为每个特定的数据查询执行此操作案件。 还存在需要更多数据的问题。 如果您想要一组用户博客文章及其相关评论并且还想要另一组不相关的数据怎么办 通常您分别对REST API进行两次调用。 实际上在检索所有必需的数据时REST API交互可能会在特定的API交互过程中导致数十个调用。 同样在现代宽带上并且用户相对较少这是有效的。 随着成千上万甚至数十亿的用户它崩溃了。 毫秒效率至关重要。 减少网络呼叫的数量很重要。 必须有一种更好的方法一种更通用的方法以允许前端仅请求其所需的数据并通过组合对数据的请求来减少网络交互的次数。 这就是Facebook开发GraphQL的原因。 它提供了一个框架来描述您的数据模型并允许数据的使用者确切地要求他们想要什么并检索可预测的结果。 什么时候使用GraphQL GraphQL具有强大的功能和灵活性并且在Internet规模上使用时可以显着提高传统REST API的性能。 那你为什么不使用它呢 好吧以我的经验在较小的项目中我觉得我经常只是将很多REST逻辑转移到GraphQL模式定义中在那里验证和授权代码最终嵌套在一个相当丑陋的巨大模式中。 我还觉得我在重复数据类型定义一次是在GraphQL中另一次是在ORM中这可能不是所有实现的问题。 GraphQL还带来了一系列独特的安全问题–它没有错。 它与使用REST API或SQL查询将有所不同因此您需要花一些时间来研究安全性。 我会考虑在应用程序Swift扩展或数据集可能随时间显着发展的情况下使用它。 如果我在一个较小的项目中只有一组定义良好的数据那么我可能只会坚持使用REST API。 如何使用GraphQL 从开发人员的角度来看有两个主要组件 类型说明 查询语言 类型描述最终看起来很像ORM如果您熟悉的话。 您定义类型和这些类型上的字段。 稍后您还将定义函数以从数据库中检索该信息。 例如让我们看一个非常简单的博客文章定义。 type Post { id: ID! text: String!
} 很基本。 post具有id和text字段。 让我们在Post类型定义中添加一些注释。 type Post { id: ID! text: String! comments: [Comment!]!
} type Comment { id: ID! text: String!
} 现在Post类型包含一个Comments类型的数组。 我们如何将其转换为可用的GraphQL模式定义 我们需要做两件事 定义“查询”类型-所有GraphQL查询进入我们数据的入口点 为每种类型的每个字段编写方法这些方法从数据类型返回所请求的字段 定义GraphQL模式查询 在简单的示例应用程序我们正在建立我们希望能够查询的帖子所以让我们来添加一个查询类型与post Post类型的字段。 我们的GraphQL模式现在看起来像这样 type Query { post(id: ID!): Post
}type Post { id: ID! text: String! comments: [Comment!]!
} type Comment { id: ID! text: String!
} 重申一下Post和Comment类型直接描述了我们的数据结构而Query类型则是GraphQL-ism这是一种特殊类型用于定义模式的只读入口点。 还有一种Mutation类型可在架构中提供可变的访问点。 要注意的另一件事是字段可以有参数。 如果查看Query类型上的post字段您会注意到它具有ID类型的参数。 可以在查询中指定此参数并将该参数传递给调用该函数以检索数据。 顺便说一句感叹号仅表示该类型不可为空。 GraphQL中的类型 GraphQL基本上是关于在类型上定义字段并查询这些字段。 它是强类型的并且具有5种内置标量类型 Int32位整数 浮点数带符号的双精度浮点值 字符串UTF-8字符序列 布尔值对或错 ID唯一标识符序列化为字符串 还可以定义自定义标量类型例如Date类型并且必须提供用于序列化反序列化和验证的方法。 也可以指定枚举和列表/数组。 我们在上面的Post类型中创建了Comments列表。 GraphQL官方文档提供了有关类型和架构的更多信息。 在Java中使用GraphQL 在本教程中我们将使用一个名为graphql-tools的项目将GraphQL与Spring Boot集成在一起。 根据项目github页面自述文件 graphql-tools “允许您使用GraphQL模式语言来构建您的graphql-java模式并允许您BYOO带上自己的对象来填充实现。” 如果您拥有或想要拥有定义数据模型的普通旧Java对象POJO则此方法非常有用。 我做的。 我们的POJO会是什么样 class Post { protected int id; protected String text; Post(int id) { this.id id; this.text ; this.comments new ArrayList(); } Post(int id, String text, ArrayList comments) { this.id id; this.text text; this.comments comments; } protected ArrayList comments; }class Comment { private int id; private String text; Comment(int id, String text) { this.id id; this.text text; } } 这些类将定义我们的数据模型的基本类型并将与GraphQL模式中的类型相对应。 它们将在单独的Java类文件中定义。 明白我对重复数据定义的意思吗 我们还需要定义几个“解析器”。 graphql-tools使用解析器来解析非标量类型。 GraphQL架构中包含非标量类型的每种类型都需要具有关联的解析器。 因此我们的Query类型和Post类型需要解析器而我们的评论类型则不需要解析器。 这是后解析器的外观 class PostResolver implements GraphQLResolver { public List getComments(Post post) { return post.comments; }
} 这是查询解析器的框架 class Query implements GraphQLQueryResolver { Post getPost(int id) {// Do something to retrieve the post}
}下载Spring Boot示例应用程序 现在我们进入了令人兴奋的部分 构建一个使用GraphQL的Spring Boot应用程序并使用Okta保护该应用程序我们将继续讲到这Okta使超级简单。 现在是继续下载示例应用程序的好时机。 它基于graphql-java github页面上这个很棒的项目中的example-graphql-tools项目。 git clone https://github.com/oktadeveloper/okta-springboot-graphql-example.git 该项目实际上是两个子项目 OktaShowToken 用于从Okta OAuth OIDC应用程序检索工作授权令牌 OktaGraphQL 基于GraphQL的 Spring Boot资源服务器我们将在最后添加Okta Auth 创建Okta OAuth应用程序并安装HTTPie 本教程假设您已经有一个免费的Okta Developer帐户如果没有为什么不直接转到developer.okta.com并创建一个。 为什么选择Okta 在Okta我们的目标是使身份管理比您以往更加轻松安全和可扩展。 Okta是一项云服务允许开发人员创建编辑和安全地存储用户帐户和用户帐户数据并将它们与一个或多个应用程序连接。 我们的API使您能够 验证和授权用户 存储有关您的用户的数据 执行基于密码的社交登录 通过多因素身份验证保护您的应用程序 以及更多 查看我们的产品文档 在Okta中创建新的OIDC应用 要在Okta上创建新的OIDC应用您可以从默认设置开始然后 登录到您的开发人员帐户导航到“ 应用程序” 然后单击“ 添加应用程序” 。 选择“ Web” 然后单击“ 下一步” 。 为应用程序命名添加http://localhost:8080/login作为登录重定向URI然后单击完成 。 我们将使用HTTPie一个出色的HTTP命令行客户端。 因此如果尚未安装该产品请签出该产品然后按照httpie.org上的安装说明进行操作 。 查看OktaGraphQL示例应用程序 让我们暂时忽略OktaShowToken项目看看OktaGraphQL它最初配置为无需身份验证即可运行。 您会注意到除了com.okta.springbootgraphql.resolvers包中的POJO类和解析器以及src/main/resources/graphql-tools.graphqls的GraphQL模式定义之外它并没有太多src/main/resources/graphql-tools.graphqls 。 在这一点上大多数应该是不言自明的。 我只是指出我们的Query类查询解析器是一种快速而肮脏的技巧以避免必须设置实际的数据库数据源。 我们只是根据ID编号即时生成Post和Comment 。 在实际的实现中您将在此处添加一些其他业务层逻辑例如授权并在数据源中查找数据。 class Query implements GraphQLQueryResolver { Post getPost(int id) { if (id 1) { ArrayList comments new ArrayList() {{ add(new Comment(1, GraphQL is amazing!)); }}; return new Post(id, Okta GraphQL is pretty sweet., comments); } else if (id 2) { ArrayList comments new ArrayList() {{ add(new Comment(1, I cant believe how easy this is.)); }}; return new Post(id, Is GraphQL better than a REST API?, comments); } else { return null; } }
}运行您的第一个GraphQL查询 打开一个终端从OktaGraphQL项目目录使用./gradlew bootRun命令启动Spring Boot应用程序。 开始可能需要几秒钟。 您应该看到一些结束像这样的输出 Tomcat started on port(s): 9000 (http) with context path
Started GraphQLToolsSampleApplication in 19.245 seconds (JVM running for 19.664) 使该终端窗口保持打开状态然后打开另一个终端窗口。 再次导航到项目根目录。 使用以下命令运行我们的第一个GraphQL查询 http POST http://localhost:9000/graphql/ json-requests/post1-all-data.json 在这里我们以内容类型application/json发出POST请求因为这是HTTPie的默认HTTPie 并且我们将在json-requests/post1-all-data.json文件中找到的查询作为请求正文发送。 来自json-requests/post1-all-data.json的请求主体 { query: { post(id: 1) { id, text, comments { id, text} } }
} 预期结果 HTTP/1.1 200
Content-Length: 122
Content-Type: application/json;charsetUTF-8
Date: Fri, 03 Aug 2018 21:50:25 GMT{data: {post: {comments: [{id: 1,text: GraphQL is amazing!}],id: 1,text: Okta GraphQL is pretty sweet.}}
} 此时您可以使用JSON请求文件请求较少的数据或请求其他帖子。 我们将继续添加身份验证。 为Okat添加Okta 此时您需要从Okta OAuth应用程序设置中获取一些信息 客户编号 客户机密 您的Okta基本网址类似这样的内容 https://dev-123456.oktapreview.com : https://dev-123456.oktapreview.com 可以在应用程序的常规设置中找到客户端ID和客户端密钥选择“ 应用程序”菜单选择要使用的应用程序最后选择“ 常规”选项卡。 在OktaGraphQL项目中创建gradle.properties文件并填写以下属性 oktaClientId{yourClientId}
oktaBaseUrlhttps://{yourOktaDomain} 在src/main/resources/application.yml文件中添加以下属性 okta: oauth2: issuer: ${oktaBaseUrl}/oauth2/default clientId: ${oktaClientId} scopes: email profile openid 将以下依赖项添加到OktaGraphQL项目中的build.gradle文件中。 这些是Spring Boot OAuth依赖项和Okta Spring Boot启动器 。 compile group: com.okta.spring, name: okta-spring-boot-starter, version: 0.6.0
compile group: org.springframework.security.oauth, name: spring-security-oauth2, version: 2.3.3.RELEASE
compile (org.springframework.security.oauth.boot:spring-security-oauth2-autoconfigure:2.0.1.RELEASE) 现在我们向GraphQLToolsSampleApplication类添加两个注释 EnableResourceServer和EnableOAuth2Sso 。 它看起来应该像这样 package com.okta.springbootgraphql; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.oauth2.client.EnableOAuth2Sso;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; SpringBootApplication
EnableResourceServer
EnableOAuth2Sso
public class GraphQLToolsSampleApplication { public static void main(String[] args) { SpringApplication.run(GraphQLToolsSampleApplication.class, args); }
} 停止您的Spring Boot应用程序如果它仍在运行然后使用./gradlew bootRun重新启动它。 对GraphQL服务器运行查询您将看到401错误 HTTP/1.1 401
Cache-Control: no-store
Content-Type: application/json;charsetUTF-8
Date: Fri, 03 Aug 2018 22:10:50 GMT
Pragma: no-cache
Transfer-Encoding: chunked
WWW-Authenticate: Bearer realmapi://default, errorunauthorized, error_descriptionFull authentication is required to access this resource
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; modeblock{error: unauthorized,error_description: Full authentication is required to access this resource
}获取访问令牌 要立即访问受保护的GraphQL服务器我们需要Okta访问令牌。 通常这可以通过应用程序前端的上下文进行管理。 在本教程中我们将使用OktaShowToken应用程序从Okta应用程序检索授权令牌。 在OktaShowToken项目中创建gradle.properties文件并填写以下属性 oktaClientId{yourClientId}
oktaClientSecret{yourClientSecret}
oktaBaseUrlhttps://{yourOktaDomain} 打开一个终端转到OktaShowToken项目根目录然后运行./gradlew bootRun 。 应用程序启动完成后导航至http://localhost:8080 。 您将完成Okta登录和身份验证过程。 您应该看到Okta登录屏幕。 登录后您将看到一个包含访问令牌的文本页面。 让此页面保持打开状态和/或将此令牌复制到以后可以使用的位置。 使用访问令牌访问GraphQL端点 首先让我们将令牌值存储在一个临时的shell变量中 TOKEN{accessTokenValue} 然后让我们再次设置授权标头来运行请求。 您需要从OktaGraphQL目录运行以下命令。 http POST http://localhost:9000/graphql/ Authorization:Bearer $TOKEN json-requests/post1-all-data.json 您应该看到以下熟悉的结果 HTTP/1.1 200
Cache-Control: no-cache, no-store, max-age0, must-revalidate
Content-Length: 122
Content-Type: application/json;charsetUTF-8
Date: Fri, 03 Aug 2018 22:22:00 GMT
Expires: 0
Pragma: no-cache
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; modeblock{data: {post: {comments: [{id: 1,text: GraphQL is amazing!}],id: 1,text: Okta GraphQL is pretty sweet.}}
}了解有关Spring BootGraphQL和安全API设计的更多信息 就是这样 GraphQL显然是一门很深的主题如果您来自传统的REST API背景则需要对其进行一些深入的研究以转变范例并正确实现所有内容。 GraphQL人员在他们的文档中反复指出 GraphQL不会替代您的业务逻辑层 而是提供一种位于您的业务逻辑层和外界之间的数据访问查询语言和类型架构。 看看他们的授权文档以了解一下。 但是正如您所看到的Okta的Spring Boot Starter使保护GraphQL端点非常简单。 如果您有兴趣了解有关Spring Boot或GraphQL的更多信息请查看以下相关文章 使用ReactGraphQL和用户身份验证构建运行状况跟踪应用 Spring BootOAuth 2.0和Okta入门 使用Spring Boot和OAuth 2.0进行安全的服务器到服务器通信 确保Spring Boot应用程序安全的10种绝佳方法 如果您对此帖子有任何疑问请在下面添加评论。 有关更多精彩内容 请在Twitter上关注oktadev 在Facebook上关注我们或订阅我们的YouTube频道 。 “我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕 尝试使用Okta API进行托管身份验证授权和多因素身份验证。 使用Spring Boot和GraphQL构建安全API最初于2018年8月16日发布在Okta开发人员博客上。 翻译自: https://www.javacodegeeks.com/2018/08/build-a-secure-api-with-spring-boot-and-graphql.html