Closed Kenjiang110 closed 4 years ago
Can you talk about it in detail? For example: Steps to reproduce the problem.
1.Tiered Template by download from abp.io, not CLI
ken_yhy@163.com
From: maliming Date: 2019-07-11 08:47 To: abpframework/abp CC: Kenjiang110; Author Subject: Re: [abpframework/abp] Dynamic JavaScript Proxies not Work in Tiered Template (#1469) Can you talk about it in detail? — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
Can't reproduce your problem.
Can you tell me which code response for the proxy generating? So I can check it.
Ken Jiang 邮箱:ken_yhy@163.com |
---|
Signature is customized by Netease Mail Master
On 07/11/2019 09:58, maliming wrote:
Can't reproduce your problem.
— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.
Creating new mvc tiered solution by Abp CLI can also be affected by this bug.
hi @Kenjiang110 @gdlcf88 The Web project does not generate Dynamic JavaScript Proxies in the Tiered template (Host will generate it). Because it does not reference the Application layer at all.
You can use Dynamic C# API Clients in your web project. (https://docs.abp.io/en/abp/latest/AspNetCore/Dynamic-CSharp-API-Clients)
I suppose you are using auto API controllers feature which is default with the startup template.
In such case, ABP can not generate Dynamic JavaScript Proxies as @maliming stated. For tiered usage, you should manually create API controllers in the .HttpApi project and call the related application service. I guess you understand the reason; because Web project will have no reference to the app layer as @maliming said. But when you create manual API controller in the HttpApi project, Web will know the API and can produce dynamic JS proxies.
Because of this reason, we always manually create API Controllers for pre-build modules to make them tiered-compatible. Example: https://github.com/abpframework/abp/blob/dev/modules/identity/src/Volo.Abp.Identity.HttpApi/Volo/Abp/Identity/IdentityUserController.cs
I analyzed the source code and believed that we shouldn't manually create API controllers. The HttpApi.Host can generate the Dynamic JavaScript Proxies, and the Web should use that one instead of generating it by itself.
The HttpApi.Host can generate the Dynamic JavaScript Proxies, yes, but client (browser) does not call REST APIs of HttpApi.Host, it uses the Web project which does not have these APIs defined in.
Still incomprehensible, why not Web project automatically request https://HttpApiHost/Abp/ServiceProxyScript
?
In general, the Web uses HttpApi.Host.
It's not easy to use APIs in Web.
I noticed that modules TenantManagement and PermissionManagement also have a "mirror image" in Web project, we can request https://web.project/api/multi-tenancy/tenants
and we can also request https://httpapi.host.project/api/multi-tenancy/tenants
.
How much waste of server's resources is there if I build conventional controllers both in Web and HttpApi.Host? Does this violate tiered architecture design?
To whoever runs into this problem too, here is what we did to enable JS proxies in a tiered project:
Include the proxy script in the web page:
<script src="https://localhost:<api-host-port>/Abp/ServiceProxyScript"></script>
In the web project, set abp.appPath
to the http api host's base url in Javascript. E.g.
abp.appPath = "https://localhost:<api-host-port>/"
Add the web host to the api host's CorsOrigins:
(in api host's appsettings.json
)
{
"<app-name>": {
"CorsOrigins": "<existing-cors-origins>,https://localhost:<web-host-port>"
}
}
Profit!
Step 2 is somewhat hacky, but I really wish the abp crews could extend this feature to make this kind of use case officially supported. I think simply allowing us to override the abp.appPath
in the proxy script (in a more elegant way) could get the job done.
@hillin I've tried the approach you have suggested but getting the following error:
Authorisation failed! Given policy has not granted:
Regards.
@jeanerasmus it should have something to do with your same site cookie policy. Read: https://web.dev/samesite-cookies-explained/
Seems like the API is not recognizing that the client is logged in, and therefor seeing the request as anonymous. I've checked the request headers and withCredentials = true. I've implemented the same site cookie workaround, but I don't think it is that, as the site works as expected with logging in and working with the default pages under administration. Any ideas?
How did you log in?
I log in via the login screen of the web application under .Web project. My identity server and API is running under different ports on localhost.
How does the API server (it's in an independent host/port if I understand correctly) know you are logged in?
Yes, I would assume that the logged in credentials are passed to the API server under the .AspNetCore.Antiforgery cookie?
No, antiforgery cookie is not for credentials. Read: https://docs.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-5.0
What is the final solution to this problem?
What is the final solution to this problem?
For now, you can use the AbpHelper GUI to generate controllers manually.
I Tried Tiered Template first and found dynamic JavasSript proxies didn't work. Then I copied the files into normal Template. It works!