express.js cookie session expire and csrf - session

I'm using express.js and mongoStore and csrf in express.js
and I want to maintain the login session for 24 hours.
so my express configuration file is like this.
// express/mongo session storage
app.use(express.session({
secret: pkg.name,
store: new mongoStore({
url: config.db,
collection : 'sessions',
auto_reconnect: true
}),
cookie:{
maxAge : new Date(Date.now() + 3600000*24) //1 Hour = 3600000
}
}))
// adds CSRF support
app.use(express.csrf())
and it works maintaining login session for 24 hours.
the problem is csrf session token also change.
Thus, after 24 hours from first login, csrf error occur on my website.
is there any way to maintaining user login session without csrf error?
thanks in advance!
:D

Related

Laravel Sanctum with SPA: Best practice for setting the CSRF cookie

Currently, my SPA is simple and has only a contact form. The form data is sent to the backend. I have installed Laravel Sanctum for that.
axios.get('/sanctum/csrf-cookie').then((response) => {
axios.post('api/contact')
.then((response) => {
//doing stuff
});
});
This works perfectly fine. However, I was wondering. Where and which time in your SPA do you fire the initial request to get the CSRF cookie? (axios.get('/sanctum/csrf-cookie'))
My first thoughts were:
Every time the page is mounted/loaded
Only when you receive a 419 and you attempt to refresh the token and retry the previous request
You don't fire any API requests, only when the user tries to log in and only then you are requesting a cookie (in my case I don't have any user authentification)
For each API request, you wrap it with axios.get('/sanctum/csrf-cookie') around
So for future readers, I chose:
Only when you receive a 419 and you attempt to refresh the token and retry the previous request
For that, I'm using the package axios-auth-refresh.
My settings look like that
//bootstrap.js
import axios from 'axios';
import createAuthRefreshInterceptor from 'axios-auth-refresh';
axios.defaults.withCredentials = true;
axios.defaults.baseURL = process.env.GRIDSOME_BACKEND_URL;
const refreshAuthLogic = (failedRequest) => axios.get('/sanctum/csrf-cookie').then((response) => Promise.resolve());
createAuthRefreshInterceptor(axios, refreshAuthLogic, { statusCodes: [419] });
window.axios = axios;

Store Laravel Passport access token in a cookie

Is it safe to store the access token in a cookie?
I've checked, and even if you have the access token, if you are not properly logged in, you will get a 401.
The access token is changing (I'm changing it) every time the user logs in.
The cookie gets destroyed on sign out or on timeout (based on the rememberme option).
Should I anyway store it somewhere else? Where about?
Yes it's safe, but still you need to add middleware on your routes
Before we are using JWT AUth, this is our solution on frontend side on login page
axios({method: 'post',
data: {email: this.email.trim(),
password: this.password},
url: '/api/login'})
.then(res => {
if (res.data.success) {
// Sets the Cookie Expiration Time to 1 Hour same as JWT Token on the Backend
var now = new Date();
now.setTime(now.getTime() + 1 * 3600 * 1000);
document.cookie = "ut=" + res.data.data.type;
document.cookie = "api_token=" + res.data.data.token;
document.cookie = "expires=" + now.toUTCString() + ";"
// Redirect to a new URL, or do something on success
window.location.href = "/dashboard";
}
}).catch(function (error) {
//error
});
Any suggestions?

Graphql remote schema stiching and cookies

I have two graphql endpoints (authentiaction endpoint [AUTH] and application endpoint [APP]).
I created the api gateway using "makeRemoteExecutableSchema" and "introspectSchema".
The thing is that [AUTH] endpoint on login mutation sets a cookie:
res.cookie("token", token, {
httpOnly: true,
secure: process.env.NODE_ENV === "production",
maxAge: 1000 * 60 * 60 * 24 * 7 // 7 days
});
The thing is, when I make a request directly to the [AUTH] endpoint, the cookie is set (I can see "Set-cookie" response headers). But when I make a login mutation via API gateway, the cookie is not set. How to solve my issue?

Keycloak logout endpoint not deleting session

Hello fellow programmes,
I am stuck on the issue with keycloak. I am trying to send from node.js express framework request towards keycloak to logout the user.
Config.keycloakClient = my_realm
Config.keycloakURL = keycloak URL
request.get({
//url: join(Config.keycloakURL, '/auth/realms/'+ Config.keycloakClient+ '/protocol/openid-connect/logout?' + 'id_token_hint='+req.headers.oidc_access_token), <--- tried this
url: join(Config.keycloakURL, '/auth/realms/'+ Config.keycloakClient+ '/protocol/openid-connect/logout'), // <-- i also tried this
headers:
{ Authorization: "Bearer " + req.headers.oidc_access_token, // <-- also tried Authorization: req.headers.oidc_access_token }
Result - 200 OK, but i can still see active session in active sessions in admin interface
request.post({
//url: join(Config.keycloakURL, '/auth/realms/'+ Config.keycloakClient+ '/protocol/openid-connect/logout?' + 'id_token_hint='+req.headers.oidc_access_token), <--- tried this
url: join(Config.keycloakURL, '/auth/realms/'+ Config.keycloakClient+ '/protocol/openid-connect/logout'), // <-- i also tried this
headers:
{ Authorization: "Bearer " + req.headers.oidc_access_token, // <-- also tried Authorization: req.headers.oidc_access_token }
Result - 302 redirect, but i can still see active session in active sessions in admin interface
I was trying to find the refresh token, but when accessing
Config.keycloakURL/auth/realms/{realm}
i could not get the refesh token-> it redirects me to the login page.
In session storage / cookies i can not see anything strange via chrome dev tools.
So what is the proper way to logout with endpoint? Which endpoint and what parameters should i use please? And how am i to obtain refresh token?
Thanks for the help!
Best regards

Dealing with axios interceptors when sending many ajax requests

I use Larave+JWT and vue2 + vuex2 + axios
So when user logins I store auth token in vuex store. When the token expires I need to refresh it. In order to refresh it I need to send the same token to /refresh route, and get a new token. At least that's how I got it and actually it works.
The problem is that interceptor catches 401 responses and tries to refresh token, but what if, say, in my component I send many requests with expired token? Since ajax requests are async, the interceptor code runs many times. So I got many refresh requests. Once the initial token is refreshed it is not considered valid. When interceptor tries to refresh invalid token server responds with error and I redirect to login page.
Here is the code:
axios.interceptors.response.use((response) => {
return response;
}, (error) => {
const originalRequest = error.config;
if (error.response.status === 401 && !originalRequest._retry) {
originalRequest._retry = true
axios.post('auth/refresh').then((response) => {
let token = response.data.token
store.dispatch('auth/setAuthToken', token)
let authorizationHeader = `Bearer ${token}`
axios.defaults.headers = { 'Authorization': authorizationHeader }
originalRequest.headers['Authorization'] = authorizationHeader
return axios(originalRequest)
}, (error) => {
store.dispatch('auth/clearAuthInfo')
router.push({ name: 'login' })
})
}
return Promise.reject(error);
});
I think you'll have to change your approach on how you refresh your token. Leaders like Auth0 recommends proactive periodic refresh to solve this problem.
Here is a SO answer where they talk about it.
Set the token expiration to one week and refresh the token every time the user open the web application and every one hour. If a user doesn't open the application for more than a week, they will have to login again and this is acceptable web application UX.

Resources