abpframework / abp

Open Source Web Application Framework for ASP.NET Core. Offers an opinionated architecture to build enterprise software solutions with best practices on top of the .NET and the ASP.NET Core platforms. Provides the fundamental infrastructure, production-ready startup templates, application modules, UI themes, tooling, guides and documentation.
https://abp.io
GNU Lesser General Public License v3.0
12.31k stars 3.32k forks source link

Dynamic JavaScript Proxies not Work in Tiered Template #1469

Closed Kenjiang110 closed 4 years ago

Kenjiang110 commented 4 years ago

I Tried Tiered Template first and found dynamic JavasSript proxies didn't work. Then I copied the files into normal Template. It works!

maliming commented 4 years ago

Can you talk about it in detail? For example: Steps to reproduce the problem.

Kenjiang110 commented 4 years ago

1.Tiered Template by download from abp.io, not CLI

  1. Multiple Startup
  2. ApplicatonService:
  3. WebApi works fine, but Dynamic JavaScript Proxy didn't be generated:

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.

maliming commented 4 years ago

Can't reproduce your problem.

Kenjiang110 commented 4 years ago

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.

gdlcf88 commented 4 years ago

Creating new mvc tiered solution by Abp CLI can also be affected by this bug.

maliming commented 4 years ago

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)

hikalkan commented 4 years ago

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

Kenjiang110 commented 4 years ago

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.

hikalkan commented 4 years ago

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.

gdlcf88 commented 4 years ago

Still incomprehensible, why not Web project automatically request https://HttpApiHost/Abp/ServiceProxyScript?

In general, the Web uses HttpApi.Host.

gdlcf88 commented 4 years ago

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?

hillin commented 2 years ago

To whoever runs into this problem too, here is what we did to enable JS proxies in a tiered project:

  1. Include the proxy script in the web page:

    <script src="https://localhost:<api-host-port>/Abp/ServiceProxyScript"></script>
  2. 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>/"
  3. 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>"
    }
    }
  4. 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.

jeanerasmus commented 2 years ago

@hillin I've tried the approach you have suggested but getting the following error:

Authorisation failed! Given policy has not granted:

Regards.

hillin commented 2 years ago

@jeanerasmus it should have something to do with your same site cookie policy. Read: https://web.dev/samesite-cookies-explained/

jeanerasmus commented 2 years ago

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?

hillin commented 2 years ago

How did you log in?

jeanerasmus commented 2 years ago

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.

hillin commented 2 years ago

How does the API server (it's in an independent host/port if I understand correctly) know you are logged in?

jeanerasmus commented 2 years ago

Yes, I would assume that the logged in credentials are passed to the API server under the .AspNetCore.Antiforgery cookie?

hillin commented 2 years ago

No, antiforgery cookie is not for credentials. Read: https://docs.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-5.0

xiangyisheng commented 2 years ago

What is the final solution to this problem?

gdlcf88 commented 2 years ago

What is the final solution to this problem?

For now, you can use the AbpHelper GUI to generate controllers manually.