asp.net - 使用 Identity 通过 React 发布 ASP.NET Core 时出现问题

标签 asp.net reactjs azure azure-web-app-service create-react-app

尝试使用 React 应用程序但使用 Identity 来发布默认的 ASP.NET Core。 Here is the MS client app readme enter image description here

这似乎可以通过直接从 Visual Studio 发布而无需身份验证。

但是一旦添加了身份,事情就会变得棘手。有了身份,我们就有了一个额外的wwwroot发布步骤中的文件夹。

here is the code for the app I am testingHere is the MS info I used for the identity and auth 。此应用程序在本地登录,并在我的用户 secret 中设置了

{
  "Authentication:Microsoft:ClientId": "IdValue",
  "Authentication:Microsoft:ClientSecret": "SecrectValue"
}

一旦发布,它将抛出 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0在控制台中。但同样,不是在本地。

发布的文件夹结构没有身份

wwwroot
├── ClinetApp
    ├── build 
        ├── static
            ├── css
            └── js
    ├── asset-manifest.json
    ├── favicon.ico
    ├── index.html
    ├── manifest.json
    ├── precache-manifest.<guid>.js
    └──service-worker.js
├── appsetting.json
├── appsetting.Development.json
├── MS-DLLs
├── App.dll
├── App.exe
├── App.pdb
├── App.deps.json
├── App.runtimeconfig.json
├── App.Views.dll
├── App.Views.pdb
└── web.config //default web config

要部署到 Azure,请使用此 blog post (来自 ClinetApp/ReadMe ),需要将另一个 Web 配置添加到 wwwroot 中除了移动ClinetApp/build文件夹到 wwwroot以及。就像普通的 asp.net core 应用程序一样,所有静态资源都被放入 wwwroot 中。文件夹,并且 dll 已移至父文件夹。

在没有第二个 Web 配置的情况下进行部署会在左侧出现这些错误。右侧的错误是在将第二个 Web 配置添加到身份项目后出现的。 ErrorFromWebConfig

修复两个控制台错误的身份项目的 Web 配置

<?xml version="1.0"?>
<configuration>
    <system.webServer>
<!--This section is for manifest.json not found error -->
    <staticContent>
    <mimeMap fileExtension=".woff2" mimeType="application/x-font-woff" />
    <mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />
    <mimeMap fileExtension=".json" mimeType="application/json" />
    </staticContent>
 <rewrite>
 <rules>
 <!--This section is for "could not load setting for "App" in AuthorizeService.js" error -->
    <rule name="React Routes"  stopProcessing="true">
    <match url=".*" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}"    matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}"    matchType="IsDirectory" negate="true" />
    <add input="{REQUEST_URI}" pattern="^/ (api)" negate="true" />
    </conditions>
    <action type="Rewrite" url="/" />
    </rule>
 </rules>
 </rewrite>
 </system.webServer>
</configuration>

带有身份的发布文件夹结构

├── wwwroot
    ├── static
        ├── css
        └── js
    ├── asset-manifest.json
    ├── favicon.ico
    ├── index.html
    ├── manifest.json
    ├── precache-manifest.<guid>.js
    ├── //service-worker.js is not used with idenity, see index.html code for explination 
    └── web.config //used for the routing from blog post
├── appsetting.json
├── appsetting.Development.json
├── MS-DLLs
├── App.dll
├── App.exe
├── App.pdb
├── App.deps.json
├── App.runtimeconfig.json
├── App.Views.dll
├── App.Views.pdb
└── web.config //default web config

一旦这些问题从网络配置中得到解决,index.html 似乎就无法正确读取。每个页面请求都会得到 Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0提供index.html 时。这是使用 react-router所以建议的修复之一是

-app.get('/', function (req, res) {
+app.get('/*', function (req, res) {
   res.sendFile(path.join(__dirname, 'build', 'index.html'));
 });

但由于这是使用 react 路由器,我们不会在解决方案中调用此代码。以下是 App.js , index.js ,和index.html

index.js

import 'bootstrap/dist/css/bootstrap.css';
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from 'react-router-dom';
import App from './App';
//import registerServiceWorker from './registerServiceWorker';

const baseUrl = document.getElementsByTagName('base')[0].getAttribute('href');
const rootElement = document.getElementById('root');

ReactDOM.render(
    <Router basename={baseUrl}>
        <App />
    </Router>,
  rootElement);

// Uncomment the line above that imports the registerServiceWorker function
// and the line below to register the generated service worker.
// By default create-react-app includes a service worker to improve the
// performance of the application by caching static assets. This service
// worker can interfere with the Identity UI, so it is
// disabled by default when Identity is being used.
//
//registerServiceWorker();


索引.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000">
    <base href="%PUBLIC_URL%/" />
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <!--
      Notice the use of %PUBLIC_URL% in the tags above.
      It will be replaced with the URL of the `public` folder during the build.
      Only files inside the `public` folder can be referenced from the HTML.

      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
      work correctly both with client-side routing and a non-root public URL.
      Learn how to configure a non-root public URL by running `npm run build`.
    -->
    <title>CPTest</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root"></div>
    <!--
      This HTML file is a template.
      If you open it directly in the browser, you will see an empty page.

      You can add webfonts, meta tags, or analytics to this file.
      The build step will place the bundled scripts into the <body> tag.

      To begin the development, run `npm start` or `yarn start`.
      To create a production bundle, use `npm run build` or `yarn build`.
    -->
  </body>
</html>

App.js

import React, { Component } from 'react';
import { Route } from 'react-router';
import { Layout } from './components/Layout';
import { Home } from './components/Home';
import { FetchData } from './components/FetchData';
import { Counter } from './components/Counter';
import AuthorizeRoute from './components/api-authorization/AuthorizeRoute';
import ApiAuthorizationRoutes from './components/api-authorization/ApiAuthorizationRoutes';
import { ApplicationPaths } from './components/api-authorization/ApiAuthorizationConstants';

import './custom.css'

export default class App extends Component {
  static displayName = App.name;

  render () {
    return (
      <Layout>
        <Route exact path='/' component={Home} />
        <Route path='/counter' component={Counter} />
        <AuthorizeRoute path='/fetch-data' component={FetchData} />
        <Route path={ApplicationPaths.ApiAuthorizationPrefix} component={ApiAuthorizationRoutes} />
      </Layout>
    );
  }
}

Startup.cs当试图向项目添加身份时,这些似乎也打破了没有身份的情况。

app.UseAuthentication();
app.UseIdentityServer();
app.UseAuthorization();

开发工具错误:index.html 不是 json

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 enter image description here

所以我注意到了这一点。

  1. 如果不使用身份,似乎在 wwwroot 中都可以工作
  2. 一旦需要移动身份文件,那么 wwwroot 和第二个 webconfig 中只有静态文件
  3. 似乎仍然不起作用,因为它需要 json 但获取了 index.html
  4. 登录页面实际上是一个cshtml页面。在本地主机上,react-router 重定向到该页面。 _LoginPartial.cshtml

登录页面的发布(左)与本地主机(右)

Publish vs local host

计数器页面的发布(左)与本地主机(右)(仅 react )

enter image description here

我也关注了these部署到产品的步骤。

有了身份,这有点奇怪,没有它,一切都可以直接从发布步骤开始在 azure 应用服务中运行。不确定需要更改哪些配置,或者是否有人以其他方式解决了这个问题?或者是否需要更改 React Router 的某些内容?有什么建议吗?

最佳答案

我在本地服务器和 Azure 上都遇到了同样的问题。我必须安装 SSL 证书,在本地主机上使用开发人员证书,一旦将其移动到生产服务器,您需要 SSL 证书才能使 Identityserver 工作。此外,您可以将 DevCert 移动到生产服务器,仅用于测试目的(我是在本地执行此操作的,不确定是否适用于 Azure)。我不记得如何立即做到这一点。我想我导出了 .pex 或 .cer 文件。我现在找不到我的笔记。快速搜索应该会有所帮助。

如果您决定使用本地主机开发证书,则需要像这样修改 appsetting.json(在“Key”下查看)

"IdentityServer": {
  "Clients": {
    "AdminPortal": {
      "Profile": "IdentityServerSPA"        
    }
  },
  "Key": {
    "Type": "Store",
    "StoreName": "MY",
    "StoreLocation": "LocalMachine",
    "Name": "CN=localhost"
  }
},

关于asp.net - 使用 Identity 通过 React 发布 ASP.NET Core 时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69034791/

相关文章:

python - 使用 Azure 和 Jupyter Notebook 进行面部识别

azure - Http 触发器启用 Azure 函数超时

azure - 如何在 Windows Azure VM 中启用 GPU

asp.net - CSS 文件在 asp.net 中不起作用

javascript - react : Can't export const

c# - TraceSource 和 ASP.NET : Works for Web Applications, 不是网站

reactjs - 将异步结果从父组件传递到子组件 react 功能组件

javascript - 在状态更新期间避免组件内部的刷新功能

asp.net mvc 操作中的 c# 异步方法

asp.net - 应用程序状态变量在网络场服务器中工作正常吗