【问题标题】:AJAX call to an Action with Authorize attribute in .NET Core 3.1AJAX 调用 .NET Core 3.1 中具有 Authorize 属性的操作
【发布时间】:2021-03-25 04:26:52
【问题描述】:

在我的pet project(一个歌词网站)上,我希望添加“点赞”功能,如下所示:

代码是开源的 (here's my current branch)。单击心形图标应为已登录用户的数据库添加一个赞,如果用户未登录,则应重定向到登录页面(IdentityServer 4,单独的项目和域)。

控制器动作:

[Authorize]
[Route("lyrics/like/{lyricId}")]
public async Task<IActionResult> Like(
  int lyricId)
{
  try
  {
    string userId = User.GetUserId().ToString();

    await _lyricsService.LikeLyricAsync(userId, lyricId);

    return RedirectToAction("Index", "Home");
  }
  catch
  {
    return RedirectToAction("Index", "Home");
  }
}

视图上的 JavaScript

<script>
  docReady(function () {
    let likeBtn = document.getElementById('like-btn');

    let likeLyric = (event) => {
      event.preventDefault();
      console.log('attemping to like a lyric!');

      // 1. create a new XMLHttpRequest object
      let request = new XMLHttpRequest();

      // 2. configure the request
      request.open('GET', 'https://localhost:5001/lyrics/like/@Model.Id');

      // 3. send the request over the network
      request.send();

      // 4. this will be called after the response is received
      request.onload = function () {
        if (request.status != 200) {
          // analyse http status of the response
          alert(`Error ${request.status}: ${request.statusText}`);
        } else {
          // show the result
          alert(`Done, got ${request.response.length} bytes`); // response is the server response
        }
      };

      request.onprogress = function (event) {
        if (event.lengthComputable) {
          alert(`Received ${event.loaded} of ${event.total} bytes`);
        } else {
          alert(`Received ${event.loaded} bytes`); // no Content-Length
        }
      };

      request.onerror = function () {
        alert("Request failed");
      };
    }

    likeBtn.addEventListener('click', likeLyric);
  });
</script>

我尝试通过添加以下内容来扩展 request.onload 函数:

else if (request.status === 302) {
  window.location = request.response;
}

但它似乎没有做到这一点,.send() 失败了。我在这里做错了什么?

这是正在发生的事情的屏幕截图:

错误是:

attemping to like a lyric!
govenda-sera:1 Access to XMLHttpRequest at 'https://localhost:5006/connect/authorize?client_id=bejebeje-mvc-local&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2Fsignin-oidc&response_type=code&scope=openid&code_challenge=2mUDM3-gR1jhn7E2EY7T17FkPTHikE8v-KQOBMskazM&code_challenge_method=S256&response_mode=form_post&nonce=637437449511000684.OWQ3MTM4MjItOTJhOS00YjgzLTk1OTYtYWE2ZGUyMzRlYzUyOWE1MTkwNjgtNzI2YS00OWJjLTgzYjAtOTY1MDQ1ZDU3YzE1&state=CfDJ8DxKnFiqfK1HscY3j3s4hc-YvLoUa_X_46X1CclU7U-RahgrNQULQOLJu6943zTWCYa5Q5acO7g7vx03ddXSOOKkUtxZQAMHSgnQHFzBvhXnoC2i6yS0PpGxns7oA7tuvcgnp-jxub7RePZl5QAe5BwfXWkyHtMkFAmTkuultwz5w-Duenyb4KNrZRk1RLn6TLL93BS6YfIfoozorOnvKel4cFFjxIc7F_QXgVFKZm6ud5lN2nItw5WhkDfU6qMHhUUSQXQRJqWSit4CW_1hPpbHZhJmatXWxD8mLVFcSEKMNQz2UIU00RDxBCQW09Skuy3Uoz50Vwp4dEYPtNIcolIKrLn1pJguNsYRWBw391uWO7rMy9W5DPJV44fMVe8UR5xKNUarkelFX4CzHidF-rE&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0' (redirected from 'https://localhost:5001/lyrics/like/938') from origin 'https://localhost:5001' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
govenda-sera:131 GET https://localhost:5006/connect/authorize?client_id=bejebeje-mvc-local&redirect_uri=https%3A%2F%2Flocalhost%3A5001%2Fsignin-oidc&response_type=code&scope=openid&code_challenge=2mUDM3-gR1jhn7E2EY7T17FkPTHikE8v-KQOBMskazM&code_challenge_method=S256&response_mode=form_post&nonce=637437449511000684.OWQ3MTM4MjItOTJhOS00YjgzLTk1OTYtYWE2ZGUyMzRlYzUyOWE1MTkwNjgtNzI2YS00OWJjLTgzYjAtOTY1MDQ1ZDU3YzE1&state=CfDJ8DxKnFiqfK1HscY3j3s4hc-YvLoUa_X_46X1CclU7U-RahgrNQULQOLJu6943zTWCYa5Q5acO7g7vx03ddXSOOKkUtxZQAMHSgnQHFzBvhXnoC2i6yS0PpGxns7oA7tuvcgnp-jxub7RePZl5QAe5BwfXWkyHtMkFAmTkuultwz5w-Duenyb4KNrZRk1RLn6TLL93BS6YfIfoozorOnvKel4cFFjxIc7F_QXgVFKZm6ud5lN2nItw5WhkDfU6qMHhUUSQXQRJqWSit4CW_1hPpbHZhJmatXWxD8mLVFcSEKMNQz2UIU00RDxBCQW09Skuy3Uoz50Vwp4dEYPtNIcolIKrLn1pJguNsYRWBw391uWO7rMy9W5DPJV44fMVe8UR5xKNUarkelFX4CzHidF-rE&x-client-SKU=ID_NETSTANDARD2_0&x-client-ver=5.5.0.0 net::ERR_FAILED
likeLyric

【问题讨论】:

  • 有返回值或控制台错误吗?
  • 我太傻了,抱歉,我已经添加了正在发生的事情的屏幕截图。

标签: ajax asp.net-core .net-core asp.net-core-mvc


【解决方案1】:

您不能对此 URL 进行 AJAX 调用来登录用户:

https://localhost:5006/connect/authorize?....

如果您希望用户登录/验证,则需要将浏览器重定向到该页面。

或者更好的是,如果用户未登录,不显示心形图标,最好有一个登录到喜欢按钮?否则用户可能会对他为什么需要登录感到惊讶。

【讨论】:

  • 我确实想通过 window.location = login url 在 javascript 方面进行重定向,但它不会因为它被 CORS 阻止。至于用户体验,在最初点击心形图标时,他们会得到某种 UI 交互,通知他们需要登录,然后他们可以选择继续,但也许你是对的,我应该认为更好的方法。
  • 重要的是您也不要尝试 iframe IdentityServer,用户应该会看到完整的 identityserver 登录页面。
【解决方案2】:

是cors引起的,需要后台开启cors。

public class Startup
{

public void ConfigureServices(IServiceCollection services)
{
    services.AddCors(options =>
    {
        options.AddPolicy(name: "AllowOrigins",
                          builder =>
                          {
                              builder.WithOrigins("http://example.com",
                                                  "http://www.contoso.com");
                          });
    });

    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseRouting();

    app.UseCors("AllowOrigins");

    //...
  }
}

另外,换个浏览器可以正常访问吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 2022-08-22
    • 1970-01-01
    • 1970-01-01
    • 2020-09-01
    相关资源
    最近更新 更多