尝试使用 React 应用程序但使用 Identity 来发布默认的 ASP.NET Core。 Here is the MS client app readme
这似乎可以通过直接从 Visual Studio 发布而无需身份验证。
但是一旦添加了身份,事情就会变得棘手。有了身份,我们就有了一个额外的wwwroot
发布步骤中的文件夹。
here is the code for the app I am testing 。 Here 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 配置添加到身份项目后出现的。
修复两个控制台错误的身份项目的 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
所以我注意到了这一点。
- 如果不使用身份,似乎在 wwwroot 中都可以工作
- 一旦需要移动身份文件,那么 wwwroot 和第二个 webconfig 中只有静态文件
- 似乎仍然不起作用,因为它需要 json 但获取了 index.html
- 登录页面实际上是一个cshtml页面。在本地主机上,react-router 重定向到该页面。
_LoginPartial.cshtml
登录页面的发布(左)与本地主机(右)
计数器页面的发布(左)与本地主机(右)(仅 react )
我也关注了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/