HTTP status code 401 even though I’m sending credentials in the request
You need to configure the server to not require authorization for OPTIONS
requests (that is, the server the request is being sent to — not the one serving your frontend code).
That’s because what’s happening is this:
- Your code tells your browser it wants to send a request with the
Authorization
header. - Your browser says, OK, requests with the
Authorization
header require me to do a CORS preflightOPTIONS
to ensure the server allows requests with theAuthorization
header. - Your browser sends the
OPTIONS
request without theAuthorization
header, because the whole purpose of theOPTIONS
check is to see if it’s OK to include that header. - Your server sees the
OPTIONS
request but rejects it with a 401 since it lacks the header. - Your browser expects a 200 or 204 response for the CORS preflight but instead gets that 401. So your browser stops right there and never tries the
POST
request from your code.
Further details:
The Access-Control-Request-Headers
and Access-Control-Request-Method
request headers show in the question indicate the browser’s doing a CORS preflight OPTIONS request.
And the presence of the Authorization
and Content-Type: application/json
request headers in your request are what trigger your browser do that CORS preflight — by sending an OPTIONS
request to the server before trying the POST
request in your code. And because that OPTIONS
preflight fails, the browser stops right there and never attempts the POST
.
So you must figure out what part of the server-side code on the server the request is being sent to causes it to require authorization for OPTIONS
requests, and change that so it instead responds to OPTIONS
with a 200 or 204 success response without requiring authorization.
For specific help on OPTIONS
-enabling a Spring server in particular, see the following answers:
- Disable Spring Security for OPTIONS Http Method
- Spring CorsFilter does not seem to work still receiving a 401 on preflight requests
- Response for preflight has invalid HTTP status code 401 - Spring
- AngularJS & Spring Security with ROLE_ANONYMOUS still returns 401
403 Forbidden vs 401 Unauthorized HTTP responses
A clear explanation from Daniel Irvine [original link]:
There's a problem with 401 Unauthorized, the HTTP status code for authentication errors. And that’s just it: it’s for authentication, not authorization.
Receiving a 401 response is the server telling you, “you aren’t
authenticated–either not authenticated at all or authenticated
incorrectly–but please reauthenticate and try again.” To help you out,
it will always include a WWW-Authenticate header that describes how
to authenticate.This is a response generally returned by your web server, not your web
application.It’s also something very temporary; the server is asking you to try
again.So, for authorization I use the 403 Forbidden response. It’s
permanent, it’s tied to my application logic, and it’s a more concrete
response than a 401.Receiving a 403 response is the server telling you, “I’m sorry. I know
who you are–I believe who you say you are–but you just don’t have
permission to access this resource. Maybe if you ask the system
administrator nicely, you’ll get permission. But please don’t bother
me again until your predicament changes.”In summary, a 401 Unauthorized response should be used for missing
or bad authentication, and a 403 Forbidden response should be used
afterwards, when the user is authenticated but isn’t authorized to
perform the requested operation on the given resource.
Another nice pictorial format of how http status codes should be used.
401 error when performing GET request w/ axios
The site is returning a 401
which means you are not authorised to access the URL.
Normally, this means you need to send credentials.
Now, you've said credentials: "include",
but that's a property recognised by fetch
, not axios
. The axios
equivalent is withCredentials: true
, so set that instead.
You've also said mode: "no-cors",
which is another property recognised by fetch
, not axios
. You don't want it anyway. Sending credentials requires permission via CORS, so by rejecting CORS, reject the possibility to get permission to send the credentials.
Remove that property.
401 Unauthorized Error On GET Request, Is It CORS Problem
I am having 401 Unauthorized error when sending get request.
No, you aren't. Read the error message more carefully.
It says that you are making an OPTIONS
request, not a GET
request.
The browser is making a preflight OPTIONS
request because you are trying to make a cross-origin request with an authorization
header.
The server appears to be testing for authorization for the OPTIONS request. This fails because the browser has not been given permission to send a cross-origin Ajax request with credentials.
Response for preflight has invalid HTTP status code 401 - Spring
avoid filtering and set status 200 when http method is OPTIONS
if("OPTIONS".equalsIgnoreCase(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
Related Topics
How to Convert Raw JavaScript Object to a Dictionary
What's the Best Way to Retry an Ajax Request on Failure Using Jquery
Getting Blob Data from Xhr Request
JavaScript Regex Hangs (Using V8)
How to Use Jquery in Chrome Extension
Reformat String Containing Date with JavaScript
HTML "Data-" Attribute as JavaScript Parameter
Get Value of a Custom Attribute
How to Focus on a Form Input Text Field on Page Load Using Jquery
Make Vuejs and Jquery Play Nice
Send Post Data on Redirect with JavaScript/Jquery
How to Be Notified Once a Web Font Has Loaded
Differences Between JavaScript Regexp Literal and Constructor
How to Pass the This Context to a Function
HTML Alignment Issue in One MAChine Only (Both IE8)
Css3-Animate Elements If Visible in Viewport (Page Scroll)
How to Change HTML Object Element Data Attribute Value in JavaScript