为什么此 ASP.NET Core POST 请求返回“405(方法不允许)”?

cra*_*den 5 c# asp.net-core

我有一个使用 ASP.NET Core 2.1 创建的非常简单的 API。当客户端页面从 localhost:8080 调用 API 时,位于 localhost:5000 的 API 将返回 HTTP:405。

为什么?请注意,AuthController.cs 中的 HTTP GET 测试方法按预期工作。这只是返回 HTTP:405 的 HTTP POST 请求。

控制器\AuthController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using server.Models;
using System.IdentityModel.Tokens.Jwt;
using Microsoft.IdentityModel.Tokens;
using System.Security.Claims;
using System.Text;

namespace server.Controllers
{
    [Route("api/auth")]
    [ApiController]
    public class AuthController : ControllerBase
    {

        [HttpGet, Route("test")]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }

        [HttpPost, Route("login")]
        public IActionResult Login([FromBody]LoginModel user)
        {
            if (user == null)
            {
                return BadRequest("Invalid client request");
            }

            if (user.UserName == "johndoe" && user.Password == "def@123")
            {
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

                var tokeOptions = new JwtSecurityToken(
                    issuer: "http://localhost:5000",
                    audience: "http://localhost:5000",
                    claims: new List<Claim>(),
                    expires: DateTime.Now.AddMinutes(10),
                    signingCredentials: signinCredentials
                );

                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);
                return Ok(new { Token = tokenString });
            }
            else
            {
                return Unauthorized();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

模型\LoginModel.cs

namespace server.Models
{
    public class LoginModel
    {
        public string UserName { get; set;}
        public string Password { get; set; }
    } 
}
Run Code Online (Sandbox Code Playgroud)

启动.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using System.Text;
using Microsoft.AspNetCore.Cors.Infrastructure;

namespace server
{
    public class Startup
    {
        public IConfiguration Configuration { get; }
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
            .AddJwtBearer(options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateIssuer = true,
                    ValidateAudience = true,
                    ValidateLifetime = true,
                    ValidateIssuerSigningKey = true,

                    ValidIssuer = "http://localhost:5000",
                    ValidAudience = "http://localhost:5000",
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes("superSecretKey@345"))
                };
            });

            var corsBuilder = new CorsPolicyBuilder();
            corsBuilder.AllowAnyHeader();
            corsBuilder.AllowAnyMethod();
            corsBuilder.WithOrigins("http://localhost:8080");
            corsBuilder.AllowCredentials();

            services.AddCors(options =>
            {
                options.AddPolicy("SiteCorsPolicy", corsBuilder.Build());
            });

            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            app.UseCors("SiteCorsPolicy");
            app.UseAuthentication();
            app.UseMvc();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

index.html(本地主机:8080)

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>JWT Auth</title>
    </head>
    <body>
        <p>Output:</p>
        <div id="output"></div>
        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
        <script>

            var item =  {
                UserName: "johndoe",
                Password: "def@123" 
            };

            $.ajax({
                type: "POST",
                accepts: "application/json",
                url: '/api/auth/Login',
                contentType: "application/json",
                data: JSON.stringify(item),
                error: function(jqXHR, textStatus, errorThrown) {
                alert("Something went wrong!");
                },
                success: function(result) {
                    console.log('Testing');
                }
            });

        </script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)

Mir*_*rko 3

看起来您正在发布到 /api/auth/login,但在您托管页面的服务器上(即 localhost:8080)。您是否想将其发布到http://localhost:5000/api/auth/login