HTTP request JWT - node.js

I am a little bit confused about how HTTP works.
My question is that when the server assigns a JWT token to a client after providing credentials, the server assigns token in HTTP header['Authorization']. Now the user is logged in and can make a request.
So please tell me if when the user makes an API call again, will the HTTP header['Authorization'] remain same or be changed?

The header['Authorization'] remains the same.
The server basically generates a token and sends it to the client-side.
On the client-side, the token will be saved in the request header of subsequent requests sent to the server.
Please check this resource

Yes client has to do every request with authorisation request (protected routes )
so you have to set up a axios configuration (https://github.com/axios/axios#axioscreateconfig)
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'TOKEN'}
});
And you have to know how this authentication and authorisation tokens works for this please go through this (https://blog.restcase.com/4-most-used-rest-api-authentication-methods/)

Related

Nodejs How to bypass the limitation of redirecting without data regarding external auth method?

I have a NodeJS application where I let my users to login via an external auth like Github and Google.
In the frontend I open for the client a tab in Github for example which prompts him to authorize GitHub against my application. I also do this with a callback url. Github then redirects the user back to the callback url I've configured.
Currently this callback URL is an API in my server.
The next step is to redirect the user back to my home page. However, I need to provide the user with some credentials like JWT token.
But I'm limited to send some data along with redirection action. What should I do?
I provide the following data with Github:
super({
clientID: configService.get('githubOAuthClientId', { infer: true }),
clientSecret: configService.get('githubOAuthClientSecret', { infer: true }),
callbackURL: configService.get('githubOAuthRedirectUri', { infer: true }),
scope: ['user:email'],
});
The githubOAuthRedirectUri variable holds my backend api route. Then I handle the data I receive from GitHub in this route controller. Now I want to redirect the user back to the home page but he also needs the JWT token and some more user specific data.
After receiving data from Github, you could redirect to an intermediate page, sending data in url query for example, and then the front-end app redirect to the home page.
That's my idea
I assume that the OAuth provider (Google or GitHub) will invoke your callback URL with an authorization code in a URL parameter ?code=.... Your server must then exchange this authorization code for an access token by making a token request to the OAuth provider. The response to that token request will then contain the access token, which is
either a JWT with a sub claim containing (most likely) the user's email address, see https://stackoverflow.com/a/72590693/16462950
or an "opaque" token, which your server must use in an Authorization: Bearer header of a UserInfo request.
Only after these steps do you know who the user is. Your server could put the JWT in a session cookie so that it is sent again (and must be validated again) in all subsequent requests.
If your server receives an opaque token instead of a JWT, this may be only short-lived and hence cannot be used in a session cookie. In this case, your server could construct its own JWT containing the user info.

Working with JWT , how to set it and use it for authentication?

Example Scenario :-
I am using HTML and JS in frontend .
For backend I am using Express .
For Authentication I am using JWT .
Basic thing I know is that JWT is generally set in Authorization header when it is sent back to server .
What I want :-
Let us assume client requested post /user/login route giving their credentials through form . Auth middleware will verify the credentials and generate a jwt token using some payload .
My problem starts here , how to set this jwt on the client side and get it back in the header while navigating user to an authenticated page where I want user to redirect when they successfully login .
Something like below :-
app.post('/user/login' , authMiddleware , async (req , res) => {
res.redirect('/user/createTask')
}
Assume /user/createTask is expecting jwt which it will verify before letting user to enter into the route .
So what has to be in the authMiddleware so that jwt is set in the client side in local Storage or somewhere and get it back in the Authorization header .
If there are things to be done on client side to make it work , Please suggest that too .
How this whole scenario will work ?
If you're sending the credentials through a form, then you won't be able to capture the response when you send a redirection response. The redirect will be handled by the browser, and your JS will not have access to anything that you send in the response.
For this scenario to work, you would have to call the post /user/login endpoint through javascript. Then you can receive the response from your server. Read any tokens from it (which can be e.g. in the body of the response), set the tokens somewhere in store and then call the /user/createTask endpoint. If you want to use JWTs sent in an Authorization header, you will have to call all your endpoints through javascript. The browser can't add an Authorization header to the request. You can store the token in a cookie (the response from login can set the cookie), then the browser will send the cookie together with the request.

Where and how do you generate a JWT token when authenticating a socket.io connection with Node/React?

From what I understand about Socket.io, there are multiple security issues, such as those mentioned in this stack exchange post.
For my case, I'm using socket.io in Node and socket.io-client for React, and setting up a nice line of communication, however I don't need any login from the client side, since I'm simply querying an external API from the backend and posting results to the front end. So I've decided to use the package socketio-jwt to secure the connection using jwt tokens.
To implement, the documentation contains the following example to use jwt authentication:
Server Side
io.use(socketioJwt.authorize({
secret: 'your secret or public key',
handshake: true
}));
io.on('connection', (socket) => {
console.log('hello!', socket.decoded_token.name);
});
Client Side
const socket = io.connect('http://localhost:9000', {
extraHeaders: { Authorization: `Bearer ${your_jwt}` }
});
My question is this: on the client side where does the variable your_jwt come from and how can I generate it?
The token needs to be generated by the login API. The user sends username and password to a login endpoint and then your server returns the JWT.
Now, what is this login API?
Most API server implements an HTTP endpoint (POST /login). Then the client can save it in local storage.
If your app doesn't have an HTTP server to support you can just implement this via WebSocket.
You should have an endpoint in your Node app where you generate JWT, client side will get it from that endpoint, save it in persistent storage and reuse it.

Access cookie data outside a component

I'm building a Next.js app using Strapi as a CMS and authentication server. I've managed to get a JWT from the auth endpoint, and have stored it in a cookie. To retrieve secured content from strapi I need to send this JWT in the header
I'm using Apollo to send graphQL queries to strapi, according to their documentation, I can easily set auth headers by adding this to utils/apollo.js
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = cookies.get('jwt') <-- This is what I'd like to do, but I can't figure out how to access cookies at this point.
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
How can I access cookies in the app mentioned above. It's not part of a component, though it is used to build a HOC?
While using localstorage is an option, I've read that cookies are a safer way to store data.
Using cookies with secure isn't an option - I'm not sure if strapi allows it, and also because there are multiple frontend origins vercel builds previews for all branches
Once you set the cookie it will be passed in the Cookie header so you need to retrieve it from there, not the cookies object which is only available in the browser but not available in server-side requests. In addition, if you're using CORS you will need to enable credentials both in the client and server, specifically in the client you need to set credentials: 'include'. This is required setting for cookies to work.

How to consume node-oidc-provider access_token with express?

I believe it's silly question but how to use node-oidc-provider with express? So I got access_token on the client side, sent request with Bearer {access_token} and what's next? How can I obtain user from that token? I believe oidc-provider must have some middleware or anything which can be used for that but I didn't find any documentation on that topic. The only thing I found is how to check if user is logged in:
const ctx = provider.app.createContext(req, res)
const session = await provider.Session.get(ctx)
const signedIn = !!session.account
But it doesn't work for me and it looks like it's using cookies inside by some reason so session is null in that case.
You would make a request to the user_info endpoint using the access token in the authorization header. The url would be should in the .well-known/openid-configuration endpoint of whatever route you attached the provider to.

Resources