In sveltekit, How can I get "load's fetch" from client side code?(like *.svelte) - hook

I'm making private homepage working only for login user.
When user login success, API server return token and save it to cookie.
After that, token was added to all fetch's request header at server-side "handleFetch" hooks.
All works fine with server-side rendering. But At client-side rendering needed position, I can't use "load's fetch" and also can't get token from cookies by default sveltekit functionality.
How can I solve this?

Related

CSRF - invalid token: Capacitorjs App with Node.js backend

In building a mobile app with capacitorjs from a functional web app with Node.js backend that uses the csurf library for the prevention of CSRF attacks, I am getting invalid token errors. The backend is being served from a local machine over http, for now. CORS is setup on the routes under test.
As I understand it, the csurf library provides the client two pieces of information, a secret in the form of a cookie, and a token, both of which the client sends back when making a POST request. The library then checks the expected value of the token with the calculated value (from the secret and from part of the token), and looks for them to match. (Aside: Getting the client to send back the cookies required some effort: I could make it work with a POST using form submission, but not with jQuery $.ajax.) At any rate, I was able to get the client to send back the secret (as a cookie in form submission or otherwise in AJAX POST) and the CSRF-Token, but they don't check out, i.e., the csurf library seems to expect a different answer, for example, here's an example of what the cookie and token look like in one instance:
req.cookies: { _csrf: 'W66Nq2CMcTTJeiFjJRu0gWFH' }
_csrf: 'guOiwkW0-BZguE8LKmYvW3ArKXhUGZuFN_88'
I put some log statements inside the function that checks these two values for correspondence in the csrf library that is used by the csurf library, and got this result:
csrf: secret W66Nq2CMcTTJeiFjJRu0gWFH
csrf: token guOiwkW0-BZguE8LKmYvW3ArKXhUGZuFN_88
csrf: expected guOiwkW0-cWREHVwpgMGiIMoKiSJmc4bA3HE
This kind of result happens whether I make a POST as form submission, or as an AJAX request. For the time being then, I have disabled CSRF protection on these cors routes serving the capacitorjs app.
Another issue that has me concerned is that the folks who wrote this library have this advice:
Don't ever create a GET /csrf route in your app and especially don't
enable CORS on it. Don't send CSRF tokens with API response bodies.
in Understanding CSRF. I am wondering how to send CSRF Tokens to the client, if not in API response bodies!

JSON Web Token (JWT) is too long to pass through client URL? Node.js and Express authentication

I am trying to use JWT to authenticate a user's email address. I cannot use OAuth because a user will be signing up with their work email and will need to verify using that.
I have added a field to my User model called isVerified. I have used mailgun to send an email to the user when they go to sign up that includes a link to a verification page in the form of http://{client_url}/verification/{userToken} where the userToken is a generated token using JSON web token.... the token is created using only the user's id so there is not a lot of information in the payload.
When the user clicks on this link, they are getting a 404 Not Found error. When I manually shorten the userToken in the url, then it properly connects to the correct React Component...
How do I solve this issue?
UPDATE: I just got rid of all the periods from the JWT token and it is loading like that.... so it seems to not be an issue with the length but with the periods... My react router Route path is "/verification/:userToken" ... how do I get it to not be affected by the periods?
Since this does not trigger your component to be rendered
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjIyLCJpYXQiOjE2MTEwMDY5OTUsImV4cCI6MTYxMTAwODE5NX0.D_-RI_YvE6lyHZFtkMizuHxPs3huIE87D6UKFEywYdg
and this does
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
I would suspect that it somehow worked because you got rid of the dots.
Make sure the "." in the token prevent the url from matching your "verification/token" route ? I mean react is assuming that
"verification/eyxxxx.eyzzzz"
is not a valid route.
Try calling for example "verification/test.test.test" and see if it renders your component.

Apple's MusicKit JS library example runs fine when rendered by Node.js, fails with Django

For three hours, I've been scratching my head over this.
Apple's MusicKit uses JWT tokens to authenticate.
When I npm start this Node.js example project, I can generate the JWT token, and then authorize Apple Music and collect the user token in response. This works when executing from localhost:8080. Here is a successful pop-up window.
When I launch my Django server locally which also generates valid JWT tokens, running the same exact HTML code with a fresh JWT token, I receive this from Apple: "Problem Connecting: There may be a network issue."
The only error on Apple.com's authorization page, is this: vendor-2c0b12a9762d9af673e21ccd8faf615e.js:2325 Error while processing route: woa Failed to construct 'URL': Invalid URL TypeError: Failed to construct 'URL': Invalid URL
I have confirmed that both applications are generating valid JWT tokens. I can use the tokens generated in my Django application with Postman directly with Apple API, as well as my token from the Node.js app.
I have tried:
Using JWT token from Django in the Node.js app -- works
Using JWT token from Node.js app in Django -- fails still
Allowing all hosts to Django
Allowing all CORS traffic to Django
Hosting page on an HTTPS valid cert. domain vs. locally
Different browser / computer
Accessing the authorization URL directly from Node.js in a new tab -- FAILS
Accessing the authorization URL directly from Django in a new tab -- FAILS
Breaking the JWT token and using that with Django -- FAILS and does not even open the authorization window (console says invalid token, so this further proves the token I use is valid with Django)
From steps 7 / 8, it would appear something in the referral process between when the JS script runs and the pop-up window for authorization appears is failing, as the token is clearly valid.
So what could Django (dev server) be doing that's disrupting this authorization flow? Or am I missing something else?
Okay, so I was right, it had to do with what Node.js server exposed to Apple.com when the request was made, versus what Django did.
It boiled down to the 'Referrer-Policy' policy of the Django server.
By default it is "same site" on Django, which means the referral information is not distributed to Apple.com, so Apple cannot verify the source of the request.
I added the following header to my Django view render:
# Create the render variable
response = render(request, 'apple.html'.format(settings.BASE_DIR), {'apple_developer_token': apple.get_token()})
# Attach the header
response['Referrer-Policy'] = 'origin-when-cross-origin'
# Return the render
return response
It then worked.

jwt on node - how does the client pass the token back to the server

okay.
I think I have failed to understand an elemental part of token based authentication.
I am using node with express and am using jwt to prevent access to my site if you haven't logged in. I can create a token on the login page, and I can send it back to the client and store it in localStorage/cookie. Now if the user wants to navigate to another page they will type in a url and trigger a get request.
How do I access that token from localStorage/cookie and pass it to the server before I load the page as part of the get request. My assumption is that there should be a way of passing the token to the server - intercepting it in the middleware - and loading the page if the token is legit, or redirecting to the login page if the token isn't validated correctly.
On a post request this would be much simpler as you can fetch the token and pass it as part of an ajax call, after the page has loaded.
I have seen references to including the token as part of the request header (authorization bearer). I assume this only works for post, because if you were able to set the header parameter 'globally' then why would you bother storing on the client side in a cookie/localStorage.
So as you can see I am a little confused by the workflow. It seems like I am going against the grain somehow. Any clarity would be much appreciated.
If you are using localStoage in order to store the JWT, then the easiest way to pass it to the server is by retrieving first the token from the localStorage with localStorage.getItem('token') (or whatever your token name is) and then inserting it in the header of the request (either it is GET or POST/PUT/DELETE). Depeding on the library you are using to handle your http requests on the client, there are different ways of doing so. In jQuery for example, you can do the following inside the AJAX request:
$.ajax({
url: API_URL + "/endpoint",
method: "GET",
beforeSend: function(request){
request.setRequestHeader("Authorization", "BEARER " + localStorage.getItem('token'));
}
})
After this, on the server side simply access the parameters by accessing request.header options just as you would normally do. Hope this helps!

Protect non-api (res.render) route with express-jwt token in Node.js

First of all, I have read all tutorials on protecting REST API routes with jwt (express-jwt & jsonwebtoken), and it works fine for that purpose.
This works fine:
app.use('/api', postApiRoute);
And this also works, somewhat, I mean.. it does verify the token when I use it to show a webpage with angular http request calls, but when you add expressJwt({secret: secret.secretToken}), you cannot just access localhost:3000/api/post anymore. The expressJwt({secret: secret.secretToken}) is the problem here.
app.use('/api', expressJwt({secret: secret.secretToken}));
app.use('/api', userApiRoute);
What I really need is to protect a non-json but html/text request route with jwt like eg.:
app.get('/admin*', expressJwt({secret: secret.secretToken}), function(req, res){
res.render('index', {
//user: req.session.user, <- not sure how to do the equivalent, to extract the user json-object from the express-jwt token?
js: js.renderTags(),
css: css.renderTags()
});
});
.. without having to make http requests in angular/js, but using express' render function.
I need to do this since my application has 2 primary server routed views, so 1 where admin scripts are loaded from, and 1 where the frontend (theme) assets gets loaded.
I cant however get jwt/tokens to work with server rendered views, only json api requests.
The error i'm getting is: "UnauthorizedError: No Authorization header was found"
Couldn't find any information about (server rendered views protected with jwt, only serverside api requests and client side angular/ajax http requests) this, so I hope my question is clear, and that I do not have to fall back to using sessions again.
Not sure if I understood correctly, but if you are talking about entry html routes (i.e., loaded directly by the browser and not by you angular app), then you simply have no way of instructing the browser as to how to set the authorization header (no without introducing some other redirect based auth flow).

Resources