简体   繁体   中英

CORs Preflight Errors With Authenticated ASP.Net Core 3.1 API + Reactjs/Axios

currently deploying my first aspnet core backend API. I've spent the past several days wrestling with CORs. I've been able to get past it for my endpoints that use [Allow Anonymous] but as soon as I try accessing endpoints that have authentication or accessing anonymous endpoints with a bearer token I get a CORs preflight error. I've attached screen caps of the error I'm receiving/details. CORsError1 CORsError2

Here is my project files for front/back end.

https://github.com/evandagrift/Codex-Royale-API

https://github.com/evandagrift/ClashCodexReactSite

My Startup looks like this in ASPNet

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

            public IConfiguration Configuration { get; }

            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddCors(options =>
                {
                    options.AddDefaultPolicy(
                        builder =>
                        {
                            builder
                            .AllowCredentials()
                            .WithMethods("POST","GET", "PUT", "DELETE")
               .AllowAnyHeader()
               .WithOrigins("http://localhost:3000")
               ;
                        });
                });
                services.AddControllers();




                services.AddDbContext<TRContext>(options => options.UseMySQL(Configuration["ConnectionStrings:DBConnectionString"]));


                services.AddAuthentication("Basic").AddScheme<AuthenticationSchemeOptions, CustomAuthenticationHandler>("Basic", null);

                services.AddAuthorization(options =>
                {
                    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
                    options.AddPolicy("All", policy => policy.RequireRole("Admin", "User"));
                });

                services.AddSingleton<CustomAuthenticationManager>();
                services.AddSingleton<string>(Configuration["ConnectionStrings:BearerToken"]);
                //allow connection between origins

            }

            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                var officialToken = Configuration["ConnectionStrings:BearerToken"];
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }

                app.UseHttpsRedirection();

                app.UseRouting();

                app.UseCors("Default");

                app.UseAuthorization();
                app.UseAuthentication();

    //            // global cors policy
    //            app.UseCors(builder =>
    //            {builder
    //   .AllowAnyHeader()
    //.WithOrigins("http://localhost:3000/")
    //   .AllowAnyMethod();
    //            });

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers().RequireCors("Default");
                });
            }
        }

My Axios setup looks like this

import Axios from "axios";
const corsFix = 'https://cors-anywhere.herokuapp.com/';
const baseURL = "https://www.royaletracker.com/api/";
const localURL = "//localhost:52003/api/"
let headers = {};
if (localStorage.user){
   headers.Authorization = `bearer ${localStorage.user['token']}`;
}
export const axios = Axios.create({baseURL:baseURL,
headers,
});

and usage that is failing

import React, {useState, useContext} from "react";
import {UserContext} from "../UserContext";
import { axios } from "../Axios"
import { Link } from "react-router-dom";

const UserSettings = () => {    
    const {user, setUser} = useContext(UserContext);
    const[password, setPassword] = useState('');
    const[email,setEmail] = useState('');
    const[role,setRole] = useState('');
    const[tag,setTag] = useState('');
    const[clanTag,setClanTag] = useState('');

    //check legitimacy of either user or clan Tag
    const UpdateUser = (e) => {
        e.preventDefault();
        const config = {headers: { Authorization: `bearer ${user['token']}`}};
        
        //axios headers
        //bearer assign
        //put
      

      
      axios.put('Users', {
        Username: user['username'],
        Password: user['password'],
        Token: user['token'],
        Email: email,
        Tag: tag,
        ClanTag: clanTag,
        Role: role
      },config)
      .then((response) => {
        console.log("Update: " + response);
      }, (error) => {
        console.log(error);
      });

        //make put request w/ Bearer Token
    }

//make switch based of role level
//end users can't change
//Username
//role
//token
    
    return (
        <div>
            <form onSubmit={UpdateUser}>
                <h1 className="h3 mb-3 fw-normal">Change your profile settings: <b>{user['username']}</b> </h1>
                <label>Email
                <input type="email"id="inputEmail" className="form-control" placeholder={user['email']} onChange={e => setEmail(e.target.value)}required/>
                </label>
                
                <label>Tag
                <input type="tag" id="inputTag" className="form-control" placeholder={user['tag']} onChange={e => setTag(e.target.value)}required />
                </label>

                <label>ClanTag
                <input type="clantag" id="inputClanTag" className="form-control" placeholder={user['clanTag']} onChange={e => setClanTag(e.target.value)}required />
                </label>

                <label>Role
                <input type="role" id="inputRole" className="form-control" placeholder={user['role']} onChange={e => setRole(e.target.value)}required />
                </label>
                <br/>
                <Link className="link" to="/logintest">change password</Link>

                <br/>
                <button className="w-100 m-2 btn btn-lg btn-primary" type="submit">Update User</button>
            </form>
        </div>
    );
};

export default UserSettings;

I'm assuming this is failing because of interaction with authentication. Any advice would be super helpful.

Side Note I'm getting this cors error when I try connecting to the backend hosted locally even on [AllowAnonymous] endpoints.

Local CORs Error1 Local CORs Error2

Also, I'm looking for my first Jr Dev job, if you're hiring feel free to message me!

currently deploying my first aspnet core backend API. I've spent the past several days wrestling with CORs. I've been able to get past it for my endpoints that use [Allow Anonymous] but as soon as I try accessing endpoints that have authentication or accessing anonymous endpoints with a bearer token I get a CORs preflight error. I've attached screen caps of the error I'm receiving/details. CORsError1 CORsError2

Here is my project files for front/back end.

https://github.com/evandagrift/Codex-Royale-API

https://github.com/evandagrift/ClashCodexReactSite

My Startup looks like this in ASPNet

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

            public IConfiguration Configuration { get; }

            // This method gets called by the runtime. Use this method to add services to the container.
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddCors(options =>
                {
                    options.AddDefaultPolicy(
                        builder =>
                        {
                            builder
                            .AllowCredentials()
                            .WithMethods("POST","GET", "PUT", "DELETE")
               .AllowAnyHeader()
               .WithOrigins("http://localhost:3000")
               ;
                        });
                });
                services.AddControllers();




                services.AddDbContext<TRContext>(options => options.UseMySQL(Configuration["ConnectionStrings:DBConnectionString"]));


                services.AddAuthentication("Basic").AddScheme<AuthenticationSchemeOptions, CustomAuthenticationHandler>("Basic", null);

                services.AddAuthorization(options =>
                {
                    options.AddPolicy("AdminOnly", policy => policy.RequireRole("Admin"));
                    options.AddPolicy("All", policy => policy.RequireRole("Admin", "User"));
                });

                services.AddSingleton<CustomAuthenticationManager>();
                services.AddSingleton<string>(Configuration["ConnectionStrings:BearerToken"]);
                //allow connection between origins

            }

            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                var officialToken = Configuration["ConnectionStrings:BearerToken"];
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }

                app.UseHttpsRedirection();

                app.UseRouting();

                app.UseCors("Default");

                app.UseAuthorization();
                app.UseAuthentication();

    //            // global cors policy
    //            app.UseCors(builder =>
    //            {builder
    //   .AllowAnyHeader()
    //.WithOrigins("http://localhost:3000/")
    //   .AllowAnyMethod();
    //            });

                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers().RequireCors("Default");
                });
            }
        }

My Axios setup looks like this

import Axios from "axios";
const corsFix = 'https://cors-anywhere.herokuapp.com/';
const baseURL = "https://www.royaletracker.com/api/";
const localURL = "//localhost:52003/api/"
let headers = {};
if (localStorage.user){
   headers.Authorization = `bearer ${localStorage.user['token']}`;
}
export const axios = Axios.create({baseURL:baseURL,
headers,
});

and usage that is failing

import React, {useState, useContext} from "react";
import {UserContext} from "../UserContext";
import { axios } from "../Axios"
import { Link } from "react-router-dom";

const UserSettings = () => {    
    const {user, setUser} = useContext(UserContext);
    const[password, setPassword] = useState('');
    const[email,setEmail] = useState('');
    const[role,setRole] = useState('');
    const[tag,setTag] = useState('');
    const[clanTag,setClanTag] = useState('');

    //check legitimacy of either user or clan Tag
    const UpdateUser = (e) => {
        e.preventDefault();
        const config = {headers: { Authorization: `bearer ${user['token']}`}};
        
        //axios headers
        //bearer assign
        //put
      

      
      axios.put('Users', {
        Username: user['username'],
        Password: user['password'],
        Token: user['token'],
        Email: email,
        Tag: tag,
        ClanTag: clanTag,
        Role: role
      },config)
      .then((response) => {
        console.log("Update: " + response);
      }, (error) => {
        console.log(error);
      });

        //make put request w/ Bearer Token
    }

//make switch based of role level
//end users can't change
//Username
//role
//token
    
    return (
        <div>
            <form onSubmit={UpdateUser}>
                <h1 className="h3 mb-3 fw-normal">Change your profile settings: <b>{user['username']}</b> </h1>
                <label>Email
                <input type="email"id="inputEmail" className="form-control" placeholder={user['email']} onChange={e => setEmail(e.target.value)}required/>
                </label>
                
                <label>Tag
                <input type="tag" id="inputTag" className="form-control" placeholder={user['tag']} onChange={e => setTag(e.target.value)}required />
                </label>

                <label>ClanTag
                <input type="clantag" id="inputClanTag" className="form-control" placeholder={user['clanTag']} onChange={e => setClanTag(e.target.value)}required />
                </label>

                <label>Role
                <input type="role" id="inputRole" className="form-control" placeholder={user['role']} onChange={e => setRole(e.target.value)}required />
                </label>
                <br/>
                <Link className="link" to="/logintest">change password</Link>

                <br/>
                <button className="w-100 m-2 btn btn-lg btn-primary" type="submit">Update User</button>
            </form>
        </div>
    );
};

export default UserSettings;

I'm assuming this is failing because of interaction with authentication. Any advice would be super helpful.

Side Note I'm getting this cors error when I try connecting to the backend hosted locally even on [AllowAnonymous] endpoints.

Local CORs Error1 Local CORs Error2

Also, I'm looking for my first Jr Dev job, if you're hiring feel free to message me!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM