Home > Back-end >  Unable to access Authorization header in Svelte
Unable to access Authorization header in Svelte

Time:06-02

I am new to Svelte, and am trying to create a login page to an API. The API takes a username and password and returns an Authorization header. I see the authorization header in the F12 developer console, and I am able to access other headers via code, but not the Authorization header. I have enabled CORS on the server for localhost:8080.

<script>
    const BASE_URL = ...;

    export let username;
    export let password;

    let result;
    let status;
    let body;
    let token;
    let contentType;

    async function doPost () {
        const res = await fetch(BASE_URL   'authenticate', {
            method: 'POST',
            mode: 'cors',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                'username': username,
                'password': password
            })
        });

        const text = await res.text();
        status = res.status;
        result = text;
        token = res.headers.get('Authorization');
        contentType = res.headers.get('Content-type');
        if (!res.ok) {
            throw new Error(result);
        }

    }

</script>
Please log in<br>
<input type="text" bind:value={username}/>
<br>
<input type="password" bind:value={password}/>
<br>
<button type="button" on:click={doPost}>Log in</button>
<br>
Result: {result}
<br>
Status: {status}
<br>
Token: {token}
<br>
Content-type: {contentType}

Response headers are as follows:

HTTP/1.1 200 
Server: nginx/1.20.0
Date: Tue, 31 May 2022 18:59:09 GMT
Content-Type: text/plain;charset=UTF-8
Content-Length: 8
Connection: keep-alive
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:8080
Authorization: Bearer xyz...

The page displays as follows after logging in:

Result: Welcome!
Status: 200
Token: null
Content-type: text/plain;charset=UTF-8

Server side (spring boot) has the following annotation on the authenticate method:

@CrossOrigin(origins = "http://localhost:8080", allowedHeaders = "*", allowCredentials = "true")

As you can see, I am able to access the content-type header but not the authorization header. Any assistance would be greatly appreciated.

CodePudding user response:

I figured it out. I needed to add exposedHeaders = "Authorization" to the @CrossOrigin annotation on the server side.

CodePudding user response:

I literally solved this exact problem today. So... I'm not entirely sure why you cannot access the cookies sent back in the HTTP response, I believe it has something to do with not allowing js access to cookie related data for security reasons.

A preliminary issue I see, is that you should be sending the API auth token to the frontend, in the 'set-cookie' header, along with sending it in the HTTP response body, which I assume is JSON for your API. I've never seen anyone suggest sending it in the 'Authorization' header like you have. I believe you are confused. I'll try and clarify the right way to do this and why you're most likely confused.

Your backend will generate an access token of some sort upon a successful login. Like I said, you send it back in the 'set-cookie' header, aswell as in the HTTP body.

Now when you read the response on the frontend, you can retrieve the Auth token from the HTTP response body, and use it in subsequent requests to authenticate to your backend server. The way JWT tokens are expected to be sent is in the 'Authorization' header of your request. This is where you're mixed up, the 'Authorization' header is used in subsequent authenticated requests to the server, not to send the Auth token from the backend to the frontend.

Now along with setting up the 'Authorization' header, you'll most likely need to send that same token in the 'cookie' header. You can do this by using the {withCredentials: true} option with fetch. This will send the cookie you sent in the 'set-cookie' response header after a successful login attempt, back to the server on all subsequent requests where you set this option.

Hope this helps, sorry I'm on my phone, so restricted with what I can write.

  • Related