朝阳区网站建设推广seo,信阳做网站优化,网站服务器vps,汕头网站建设制作报价“我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕#xff1f; 尝试使用Okta API进行托管身份验证#xff0c;授权和多因素身份验证。 从本质上讲#xff0c;React只是一个UI工具包#xff0c;即ala GWT#xff0c;但是… “我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕 尝试使用Okta API进行托管身份验证授权和多因素身份验证。 从本质上讲React只是一个UI工具包即ala GWT但是它周围有一个非常健康的生态系统它提供构建踢踏式渐进式Web应用程序PWA所需的一切。 PWA很酷因为如果操作正确它们可以为您的用户提供类似本机的体验允许他们安装您的应用程序并在脱机时使用它。 但是“为什么要使用React” 您现在可能会问自己是什么对吗 好吧您可能听说过Angular可以成为希望学习JavaScript的Java开发人员的入门药物。 如果您是一位熟悉Angular的经验丰富的Java开发人员那么您很可能会从AngularJS开始。 AngularJS具有与Java MVC框架类似的概念例如控制器服务和指令我相信它们类似于JSP标签恕我直言。 如果您仍在进行Angular开发则可能在此过程中学习了TypeScript。 您喜欢TypeScript因为它具有Java之类的类型并且它也是一种非常不错的语言 我敢打赌如果您已经了解Angular那么您可能想了解React的主要竞争对手。 总是有几种编写Web应用程序的方法而React提供了一种完全不同的方法来执行它您也可以将TypeScript与它一起使用 在这篇文章中我将向您展示如何构建一个安全的PWA该PWA可以上载和处理图像将它们显示在类似Flickr的网格中并使用Spring Boot作为其后端。 React和Spring Boot入门 开始使用React的最简单方法之一就是使用Create React App CRA。 您在本地安装它然后运行create-react-app $projectName生成具有最小依赖性的框架React应用程序。 它使用秘密的webpack构建项目启动Web服务器并运行其测试。 Spring Boot有一个类似的工具称为Spring Initializr 。 Spring Initializer与CRA有所不同因为它是您用来创建应用程序的网站和API。 这两个工具都值得研究您可以通过阅读我的《 使用Spring Boot和React进行Bootiful开发》教程来学习如何使用它们创建基本应用。 今天我将向您展示如何使用React和Spring Boot为照片构建CRUD应用程序。 但是我要作弊。 我将使用JHipster而不是从头开始构建所有内容。 JHipster是一个应用程序生成器最初仅支持Angular和Spring Boot。 在其5.0版本中它增加了对Reactwebpack 4和Spring Boot 2的支持。 JHipster附带了每个应用程序都需要的许多功能包括身份验证/授权单元和端到端测试支持以及使其易于部署到云的工具。 JHipster 5入门 要开始使用JHipster你需要有互联网连接和Node.js的安装。 该项目建议您使用最新的LTS长期支持版本在撰写本文时为8.3.11。 您可以使用npm但如果安装了JHipster它将使用Yarn 。 要运行该应用程序您需要安装Java 8 。 如果安装了GitJHipster将在创建项目后自动提交项目并允许您在版本之间进行升级。 运行以下命令来安装JHipster npm i -g generator-jhipster5.0.1 要使用JHipster创建图库应用请创建目录并在其中运行jhipster 。 mkdir gallery
cd gallery
jhipster JHipster询问有关您要创建的应用程序类型以及要包括哪些技术的许多问题。 下表显示了您要进行的选择 题 回答 应用类型 Monolithic application 名称 gallery Java包名称 com.okta.developer 使用JHipster注册表 No 认证类型 OAuth 2.0 / OIDC 数据库类型 SQL 生产数据库 PostgreSQL 开发数据库 H2 with disk-based persistence 使用Spring缓存 Yes, with Ehcache 使用Hibernate 2级缓存 Yes Maven还是Gradle Maven 其他技术 blank 客户框架 React 启用SASS支持 No 启用i18n Yes 应用程序的母语 English 其他语言 French 其他测试框架 Protractor 安装其他发电机 No 回答完所有这些问题后JHipster将在当前目录中创建大量文件然后运行yarn 或npm install 以安装package.json指定的所有依赖项。 验证一切适用于量角器和Keycloak 当您选择OAuth 2.0和OIDC进行身份验证时用户将存储在应用程序外部而不是存储在应用程序中。 这意味着您需要有一个身份提供程序IdP用于存储用户并允许您的应用检索有关他们的信息。 默认情况下JHipster随附用于Docker Compose的Keycloak文件。 默认的用户和组集在启动时被导入并且为您的JHipster应用程序注册了一个客户端。 这是您应用程序的src/main/docker目录中的keycloak.yml样子 version: 2
services:keycloak:image: jboss/keycloak:4.0.0.Finalcommand: [-b, 0.0.0.0, -Dkeycloak.migration.actionimport, -Dkeycloak.migration.providerdir, -Dkeycloak.migration.dir/opt/jboss/keycloak/realm-config, -Dkeycloak.migration.strategyOVERWRITE_EXISTING, -Djboss.socket.binding.port-offset1000]volumes:- ./realm-config:/opt/jboss/keycloak/realm-configenvironment:- KEYCLOAK_USERadmin- KEYCLOAK_PASSWORDadminports:- 9080:9080- 9443:9443- 10990:10990 要启动Keycloak您需要安装Docker Compose 。 然后在终端窗口中运行以下命令 docker-compose -f src/main/docker/keycloak.yml up 您可以使用Maven在一个终端中启动应用程序从而从一开始就验证一切正常 ./mvnw 然后在另一个终端上运行所有的量角器测试 yarn e2e 如果您的环境设置正确您将看到类似以下的输出 yarn run v1.7.0
$ protractor src/test/javascript/protractor.conf.js
(node:97048) [DEP0022] DeprecationWarning: os.tmpDir() is deprecated. Use os.tmpdir() instead.
[15:36:33] W/configParser - pattern ./e2e/entities/**/*.spec.ts did not match any files.
[15:36:33] I/launcher - Running 1 instances of WebDriver
[15:36:33] I/direct - Using ChromeDriver directly...Account✓ should fail to login with bad password✓ should login with admin account (2720ms)Administration✓ should load metrics✓ should load health✓ should load configuration✓ should load audits✓ should load logs7 passing (10s)[15:36:45] I/launcher - 0 instance(s) of WebDriver still running
[15:36:45] I/launcher - chrome #01 passed
✨ Done in 13.67s.在Keycloak中为您的React Spring Boot App启用用户注册 将OIDC身份验证与JHipster一起使用时似乎缺少的功能之一是用户注册。 如果您使用会话或JWT身份验证则主页上会提供一个注册链接。 使用OIDC您需要在IdP中启用它。 对于Keycloak您可以通过导航到http://localhost:9080并单击Administration Console来实现 。 使用admin/admin登录然后单击“ 登录”选项卡。 该屏幕允许您启用忘记密码记住我以及通过电子邮件进行验证。 启用此设置后您将在Keycloak的登录表单上看到“ 注册”链接。 您需要在Keycloak中为新用户配置默认角色。 导航到角色 然后单击默认角色选项卡。 选择ROLE_USER 然后单击“ 添加所选内容” 。 要配置默认组请转到“ 组” “ 默认组” 。 单击Users然后添加 。 添加默认组是必要的因为JHipster希望用户将ROLE_USER或ROLE_ADMIN组或角色作为其ID令牌声明的一部分。 保存用于JPA关系的用户数据 我添加到JHipster的功能之一是我喜欢称之为“ 保存用户快照” 。 使用JPA时很高兴能够与JHipster的User实体建立关系。 这样一来您就可以说出“此用户拥有此相册”之类的字眼并根据该信息限制访问权限。 该功能默认情况下处于启用状态其工作方式如下 登录后 /api/account发出请求。 AccountResource.java的getAccount()方法被映射到该端点并UserService#getUserFromAuthentication()给UserService#getUserFromAuthentication()以提取用户的详细信息。 getUserFromAuthentication()方法从Spring Security中提取用户的详细信息将ID令牌中的组/角色映射到授权机构并在数据库中添加/更新用户。 此功能使您可以与User实体创建关系。 唯一的缺点是当您具有具有用户关系的实体时“用户”下拉列表将仅包含已登录您的应用程序的用户。 将您的身份提供者更改为Okta JHipster利用Spring Security的OAuth 2.0支持来配置应从中获取用户信息的IDP。 将Spring Security与Spring Boot结合使用时可以在属性文件中配置大多数配置设置。 您甚至可以使用环境变量覆盖属性。 要从Keycloak切换到Okta或其他任何IdP您可以覆盖默认属性对于Spring Security OAuth。 为什么用Okta代替Keycloak Keycloak在开发中表现出色Okta具有免费的多因素身份验证电子邮件支持以及出色的生产性能。 您可以在developer.okta.com/pricing上查看其他免费功能和透明价格。 若要查看其工作原理请创建具有以下属性的~/.okta.env文件 export SECURITY_OAUTH2_CLIENT_ACCESS_TOKEN_URIhttps://{yourOktaDomain}/oauth2/default/v1/token
export SECURITY_OAUTH2_CLIENT_USER_AUTHORIZATION_URIhttps://{yourOktaDomain}/oauth2/default/v1/authorize
export SECURITY_OAUTH2_RESOURCE_USER_INFO_URIhttps://{yourOktaDomain}/oauth2/default/v1/userinfo
export SECURITY_OAUTH2_CLIENT_CLIENT_ID{clientId}
export SECURITY_OAUTH2_CLIENT_CLIENT_SECRET{clientSecret} 您需要在Okta中创建一个新的OIDC客户端然后填写变量然后才能运行。 完成此操作后可以运行以下命令来设置这些环境变量。 source ~/.okta.env 重新启动您的应用程序 瞧 -您现在正在使用Okta 如果您不知道如何在Okta上设置OIDC应用程序以下是一个简短的摘要。 在Okta上设置OIDC应用 登录到您的1563开发者帐户或者注册 如果你没有一个帐户并导航到应用程序 添加应用程序 。 单击“ Web” 然后单击“ 下一步” 。 给应用程序起一个您会记住的名称并指定http://localhost:8080/login作为登录重定向URI。 单击“完成”并记下客户端ID和密码。 您需要在一分钟内将它们复制/粘贴到文件中。 创建一个ROLE_ADMIN和ROLE_USER组“ 用户” “ 组” “ 添加组” 并将用户添加到其中。 我建议将您注册时使用的帐户添加到ROLE_ADMIN并创建一个新用户“ 用户” “ 添加人” 以添加到ROLE_USER 。 导航到API 授权服务器 然后单击一个名为default的名称进行编辑。 点击索赔标签然后添加索赔 。 将其命名为“角色”并将其包含在ID令牌中。 将值类型设置为“ Groups”并将过滤器设置为.*的正则表达式。 单击创建以完成该过程。 什么是Okta 简而言之我们使身份管理比您通常使用的更加轻松安全和可扩展。 Okta是一项云服务允许开发人员创建编辑和安全地存储用户帐户和用户帐户数据并将它们与一个或多个应用程序连接。 我们的API使您能够 验证和授权用户 存储有关您的用户的数据 执行基于密码的社交登录 通过多因素身份验证保护您的应用程序 以及更多 查看我们的产品文档 想要每月免费提供一千个用户吗 注册一个免费的开发人员帐户 完成后再回来这样您就可以了解有关使用Spring Boot 2.0和JHipster构建React PWA的更多信息 在Okta启用自助服务注册 要在Okta中启用自助服务注册您需要从Okta Developer仪表板导航到Classic UI。 在屏幕的左上角有一个可以在两者之间切换的链接。 然后导航至目录 自我注册 然后单击启用注册 。 将默认组设置为ROLE_USER 将默认重定向设置为以http://localhost:8080作为其值的自定义URL然后单击保存 。 注意如果收到错误消息http://localhost:8080 is not a valid redirect URI 那是因为需要在安全性 API 可信来源下将http://localhost:8080为可信重定向。 进行更改后导航至目录 自助服务注册然后编辑设置以再次配置自定义URL。 这次应该可以了。 提示部署应用程序后您需要将默认重定向更改为生产URL。 Okta自定义选项 除了允许自我注册外Okta还允许您自定义其登录屏幕的外观以及使用自定义域和电子邮件。 您可以在“ 登录窗口小部件指南”中有关此内容的信息。 您还可以尝试使用我们方便的实时窗口小部件页面实时自定义窗口小部件 。 创建实体以允许在您的图库上使用CRUD 我花了很多时间讨论如何保护您的应用程序现在让我们开始构建它 JHipster具有JDLJHipster域语言功能可让您在应用程序中对数据建模并从中生成实体。 您可以使用其JDL Studio功能在线完成此操作并在完成后将其保存在本地。 我为此应用创建了一个数据模型该数据模型具有一个Album Photo和Tag实体并在它们之间建立了关系。 下面是JDL Studio的屏幕截图。 为了方便起见您可以复制下面的JDL并将其保存在项目根目录下的gallery.jh文件中。 entity Album {title String required,description TextBlob,created Instant
}entity Photo {title String required,description TextBlob,image ImageBlob required,height Integer,width Integer,taken Instant,uploaded Instant
}entity Tag {name String required minlength(2)
}relationship ManyToOne {Album{user(login)} to User,Photo{album(title)} to Album
}relationship ManyToMany {Photo{tag(name)} to Tag{photo}
}paginate Album with pagination
paginate Photo, Tag with infinite-scroll 您可以使用以下命令生成实体和CRUD代码用于Spring Boot的Java用于React的TypeScript和JSX jhipster import-jdl gallery.jh 出现提示时键入a以允许覆盖现有文件。 此过程将创建Liquibase changelog文件以创建数据库表实体存储库Spring MVC控制器以及创建读取更新和删除数据对象所需的所有React代码。 它甚至会生成Jest单元测试和量角器端到端测试 该过程完成后您可以重新启动应用程序Ctrl C ./mvnw进程并重新启动它然后再次运行yarn e2e以快速确认所有内容./mvnw正确生成。 现在您可以看到JHipster非常强大。 它认识到您具有ImageBlob类型的image属性并自动创建了需要在数据库中上传和存储图像的管道 头晕 在Spring Boot API中添加图像EXIF处理 Photo实体具有一些属性可以通过从上载的照片读取EXIF可交换图像文件格式数据来计算。 您可能会问如何用Java做到这一点 值得庆幸的是Drew Noakes创建了一个元数据提取程序库来完成此任务。 在您的pom.xml添加对Drew库的依赖 dependencygroupIdcom.drewnoakes/groupIdartifactIdmetadata-extractor/artifactIdversion2.11.0/version
/dependency 然后修改PhotoResource#createPhoto()方法以设置上载图像时的元数据。 import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.jpeg.JpegDirectory;import javax.xml.bind.DatatypeConverter;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;import java.time.Instant;
import java.util.Date;public class PhotoResource {...public ResponseEntity createPhoto(Valid RequestBody Photo photo) throws Exception {log.debug(REST request to save Photo : {}, photo);if (photo.getId() ! null) {throw new BadRequestAlertException(A new photo cannot already have an ID, ENTITY_NAME, idexists);}try {photo setMetadata(photo);} catch (ImageProcessingException ipe) {log.error(ipe.getMessage());}Photo result photoRepository.save(photo);return ResponseEntity.created(new URI(/api/photos/ result.getId())).headers(HeaderUtil.createEntityCreationAlert(ENTITY_NAME, result.getId().toString())).body(result);}private Photo setMetadata(Photo photo) throws ImageProcessingException, IOException, MetadataException {String str DatatypeConverter.printBase64Binary(photo.getImage());byte[] data2 DatatypeConverter.parseBase64Binary(str);InputStream inputStream new ByteArrayInputStream(data2);BufferedInputStream bis new BufferedInputStream(inputStream);Metadata metadata ImageMetadataReader.readMetadata(bis);ExifSubIFDDirectory directory metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);if (directory ! null) {Date date directory.getDateDigitized();if (date ! null) {photo.setTaken(date.toInstant());}}if (photo.getTaken() null) {log.debug(Photo EXIF date digitized not available, setting taken on date to now...);photo.setTaken(Instant.now());}photo.setUploaded(Instant.now());JpegDirectory jpgDirectory metadata.getFirstDirectoryOfType(JpegDirectory.class);if (jpgDirectory ! null) {photo.setHeight(jpgDirectory.getImageHeight());photo.setWidth(jpgDirectory.getImageWidth());}return photo;}...
} 由于要提取信息因此可以从UI中删除字段并进行测试以便用户无法设置这些值。 在src/main/webapp/app/entities/photo/photo-update.tsx 添加metadata和metadataRows变量以及在添加照片时将其隐藏和将其更新时为只读的逻辑。 在下面的代码块中找到第一行并将其替换为以下代码。 const { description, image, imageContentType } photoEntity;const metadata (divAvGroupLabel idheightLabel forheightTranslate contentKeygalleryApp.photo.heightHeight/Translate/LabelAvField idphoto-height typenumber classNameform-control nameheight readOnly //AvGroupAvGroupLabel idwidthLabel forwidthTranslate contentKeygalleryApp.photo.widthWidth/Translate/LabelAvField idphoto-width typenumber classNameform-control namewidth readOnly //AvGroupAvGroupLabel idtakenLabel fortakenTranslate contentKeygalleryApp.photo.takenTaken/Translate/LabelAvInputidphoto-takentypedatetime-localclassNameform-controlnametakenreadOnlyvalue{isNew ? null : convertDateTimeFromServer(this.props.photoEntity.taken)}//AvGroupAvGroupLabel iduploadedLabel foruploadedTranslate contentKeygalleryApp.photo.uploadedUploaded/Translate/LabelAvInputidphoto-uploadedtypedatetime-localclassNameform-controlnameuploadedreadOnlyvalue{isNew ? null : convertDateTimeFromServer(this.props.photoEntity.uploaded)}//AvGroup/div
);
const metadataRows isNew ? : metadata; 然后在return块中删除image属性和album属性之间的JSX并将其替换为{metadataRows} 。 input idfile_image typefile onChange{this.onBlobChange(true, image)} acceptimage/* //AvGroup
/AvGroup
{metadataRows}
AvGroupLabel foralbum.titleTranslate contentKeygalleryApp.photo.albumAlbum/Translate/Label 在src/test/javascript/e2e/entities/photo/photo.spec.ts 删除在以下字段中设置数据的代码 photoUpdatePage.setHeightInput(5);
expect(await photoUpdatePage.getHeightInput()).to.eq(5);
photoUpdatePage.setWidthInput(5);
expect(await photoUpdatePage.getWidthInput()).to.eq(5);
photoUpdatePage.setTakenInput(01/01/2001 protractor.Key.TAB 02:30AM);
expect(await photoUpdatePage.getTakenInput()).to.contain(2001-01-01T02:30);
photoUpdatePage.setUploadedInput(01/01/2001 protractor.Key.TAB 02:30AM);
expect(await photoUpdatePage.getUploadedInput()).to.contain(2001-01-01T02:30); 您还可以在src/test/javascript/e2e/entities/photo/photo-update.page-object.ts删除这些字段的所有getter和setter setHeightInput(height) {this.heightInput.sendKeys(height);
}getHeightInput() {return this.heightInput.getAttribute(value);
}setWidthInput(width) {this.widthInput.sendKeys(width);
}getWidthInput() {return this.widthInput.getAttribute(value);
}setTakenInput(taken) {this.takenInput.sendKeys(taken);
}getTakenInput() {return this.takenInput.getAttribute(value);
}setUploadedInput(uploaded) {this.uploadedInput.sendKeys(uploaded);
}getUploadedInput() {return this.uploadedInput.getAttribute(value);
} 停止您的Maven进程运行yarn webpack:build 再次启动Maven然后运行yarn e2e以确保一切仍然正常。 如果您上传使用智能手机拍摄的图像则高度宽度和拍摄值均应填充。 如果不是则很可能您的图像中没有数据。 需要一些带有EXIF数据的样本照片吗 您可以从Flickr上的相册下载我的1966 VW Bus的图片。 将React照片库添加到您的React PWA中 您已经将元数据提取添加到了后端但是您的照片仍然显示在列表中而不是显示在网格中例如Flickr。 要解决此问题您可以使用React Photo Gallery组件。 使用Yarn安装它 yarn add react-photo-gallery6.0.28 或npm npm i --save-exact react-photo-gallery6.0.28 注意我首先尝试使用Leisan Kazberova的 react-photo-feed 但是在将其添加到我的项目后发现它导致了编译错误。 在src/main/webapp/app/entities/photo/photo.tsx 为Gallery添加导入 import Gallery from react-photo-gallery; 然后在结束/h2之后在render()方法和Gallery组件中添加一个photoSet变量。 render() {const { photoList, match } this.props;const photoSet photoList.map(photo ({src: data:${photo.imageContentType};base64,${photo.image},width: photo.height photo.width ? 3 : photo.height photo.width ? 1 : 4,height: photo.height photo.width ? 4 : photo.height photo.width ? 1 : 3}));return (divh2 idphoto-heading.../h2Gallery photos{photoSet} /...);
} 由于您仅修改了前端代码因此可以运行yarn start来启动webpack-dev-server实例该实例代理对后端的请求并在每次更改任何React文件时自动刷新浏览器使用Browsersync。 登录并导航到顶部导航栏中的实体 照片 。 您应该可以上传照片并在列表顶部的漂亮网格中查看结果。 您还可以在网格中添加“灯箱”功能以便单击照片并放大。ReactPhoto Gallery文档显示了如何执行此操作。 我已经将其集成到本文的示例中但是为了简洁起见这里不会显示代码。 您可以在GitHub上看到添加了Lightbox的最终photo.tsx或所需更改的差异 。 使您的React Spring Boot App成为PWA 成为PWA需要具备以下三个功能 您的应用必须通过HTTPS进行投放 您的应用必须注册服务工作者才能缓存请求并脱机工作 您的应用必须具有包含安装信息和图标的webapp清单 对于HTTPS您可以为本地主机设置证书或者甚至更好将其部署到生产环境 像Heroku和Cloud Foundry这样的云提供商将为您提供现成的HTTPS但他们不会强制使用 HTTPS。 要强制HTTPS请打开src/main/java/com/okta/developer/config/SecurityConfiguration.java并添加一条规则以在发送X-Forwarded-Proto标头时强制使用安全通道。 Override
protected void configure(HttpSecurity http) throws Exception {http....and().headers().frameOptions().disable().and().requiresChannel().requestMatchers(r - r.getHeader(X-Forwarded-Proto) ! null).requiresSecure().and().authorizeRequests()...
} 已经对workbox-webpack-plugin进行了配置以生成服务工作者但是仅在使用生产配置文件运行您的应用程序时它才有效。 这很好因为这意味着在开发时不会在浏览器中缓存数据。 要注册服务工作者请打开src/main/webapp/index.html并取消注释以下代码块。 scriptif (serviceWorker in navigator) {navigator.serviceWorker.register(./service-worker.js).then(function() { console.log(Service Worker Registered); });}
/script src/main/webapp/manifest.webapp包含了最后一个功能src/main/webapp/manifest.webapp 。 它定义了应用名称颜色和图标。 您可能需要调整这些值以适合您的应用程序。 将您的React Spring Boot应用程序部署到Heroku 要将应用程序部署到Heroku首先需要安装Heroku CLI 。 您可以通过运行heroku --version确认其安装。 如果您没有Heroku帐户请访问heroku.com并注册。 不用担心它是免费的而且您很可能会喜欢这种体验。 运行heroku login以登录到您的帐户然后使用JHipster启动部署过程 jhipster heroku 这将启动Heroku子生成器 该生成器会向您询问有关您的应用程序的几个问题您要为其命名的名称以及是否要将其部署到美国地区或欧盟。 然后它将提示您选择在本地构建还是在Heroku的服务器上使用Git进行选择。 选择Git这样您就不必上载繁琐的JAR部署过程就会开始。 如果您拥有稳定且快速的互联网连接则您的应用程序应在六分钟之内在互联网上启动 remote: ----- Compressing...
remote: Done: 134.5M
remote: ----- Launching...
remote: Released v5
remote: https://gallery-pwa.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/gallery-pwa.git* [new branch] HEAD - masterYour app should now be live. To view it runheroku open
And you can view the logs with this commandheroku logs --tail
After application modification, redeploy it withjhipster heroku
Congratulations, JHipster execution is complete!
Execution time: 5 min. 31 s. sec配置Okta的React Spring Boot应用程序并使用Lighthouse分析您的PWA分数 要将您的应用程序配置为在Heroku上与Okta一起使用请运行以下命令将与Okta相关的本地环境变量传输到Heroku。 heroku config:set \SECURITY_OAUTH2_CLIENT_ACCESS_TOKEN_URI$SECURITY_OAUTH2_CLIENT_ACCESS_TOKEN_URI \SECURITY_OAUTH2_CLIENT_USER_AUTHORIZATION_URI$SECURITY_OAUTH2_CLIENT_USER_AUTHORIZATION_URI \SECURITY_OAUTH2_RESOURCE_USER_INFO_URI$SECURITY_OAUTH2_RESOURCE_USER_INFO_URI \SECURITY_OAUTH2_CLIENT_CLIENT_ID$SECURITY_OAUTH2_CLIENT_CLIENT_ID \SECURITY_OAUTH2_CLIENT_CLIENT_SECRET$SECURITY_OAUTH2_CLIENT_CLIENT_SECRET Heroku重新启动您的应用程序后登录然后使用Lighthouse对其进行测试。 看起来不错是吗 了解有关ReactSpring BootJHipster和OAuth的更多信息 本教程向您展示了如何使用Spring BootReactJHipster和OIDC开发照相馆PWA。 它向您展示了一些有用的开放源代码库这些库可简化实现甚至生成测试。 您可以在GitHub上的oktadeveloper / okta-react-photo-gallery-example回购中找到本文中创建的示例的源代码。 我录制了一个截屏视频以逐步完成所有步骤。 在下面或在YouTube上观看嵌入式视频。 如果您想了解有关ReactSpring Boot或OAuth 2.0的更多信息建议您检查以下资源 使用Spring Boot和React进行Bootiful开发 在JHipster中使用OpenID Connect支持 什么是OAuth 2.0授权码授予类型 从JHipster Docs使用React与Redux 使用OAuth 2.0和JHipster开发微服务架构 如有任何疑问请在下面发表评论在Twitter mraible上ping我或发布到我们的开发人员论坛 。 如果您喜欢这篇文章请在其他类似的人发表时关注oktadev 。 使用ReactSpring Boot和JHipster构建图库PWA最初于2018年6月25日发布在Okta开发人员博客上。 “我喜欢编写身份验证和授权代码。” 〜从来没有Java开发人员。 厌倦了一次又一次地建立相同的登录屏幕 尝试使用Okta API进行托管身份验证授权和多因素身份验证。 翻译自: https://www.javacodegeeks.com/2018/07/react-spring-boot-photo-gallery-pwa.html