I am using express-session to save cookies into my browser so I can use it for authentication. I am sending a post request from my frontend (React) using axios to the backend and use User.register to save the new user to the database(mongodb)
I am able to save the user to my database however, there are no cookies being saved in my browser.
Frontend post request using axios:
backend post request handler
In your server add this code
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
Client axios config
const Axios= axios.create({
baseURL: "http://localhost:3001/",
withCredentials: true,
});
Related
I am using expressjs for backend and vitejs for frontend.
here is my code of backend :
app.use(express.json());
app.use(cors({credentials: true, origin: true, withCredentials: true }))
app.use(cookieParser());
db.query("COMMIT", (err) => {
if (err) return res.status(400).json(err);
const token = createToken(data[0].id, null);
const { password, ...other } = data[0];
return res.cookie("access_token", token, { httpOnly: true, sameSite: 'none', secure: true }).status(200).json(other);
});
frontend code:
await axios.post("http://localhost:8000/user/signup", inputs, { withCredentials: true })
I have tried different browser but it still not working.
If you have different frontend and backend servers (with different hostnames, not just different ports) and the HTML/Javascript served by the frontend server wants to make an HTTP request with cookies to the backend server, this cannot work, because:
Cookies from the backend count as "cross-site" in a request made from the frontend server's page. Such cookies are only sent if they have SameSite=None.
Cookies with SameSite=None must also have the Secure attribute and are then only sent over HTTPS connections.
What you could do:
In your development environment, use HTTP, cookies without SameSite or Secure attributes and have frontend and backend servers both on localhost, just on different ports.
In the production environment, use HTTPS for both frontend and backend servers, cookies with SameSite=None; Secure.
There is a server, which serves my client react app at root path. So when I make any request to server from POSTMAN, to login for example, cookies are attached perfect. But when I make request from my client using AXIOS and withCredentials field as well, cookies ain't attached, nevertheless the request is sent good, but no cookies received. I don't think there is any reason to search issues in server code, because postman works with it perfect. In case, there is no CORS errors: server provides client app. I get nice response from the server, with no cookies. Postman gets them.
axios request in react app:
export const login = createAsyncThunk(
'auth/login',
async (credentials: ILogin) => {
// todo: making a request to server
const response = await axios({
url: '/api' + '/auth' + '/login',
method: 'POST',
data: credentials,
withCredentials: true,
headers: {
'Content-Type': 'application/json'
},
});
console.log(response)
}
)
Client doesn't receive cookies, neither on localhost nor deployed app.
As you see, only place where cookies are shown it's network section in devtools, but everything else, including server acts like my second request hadn't any cookie, because in this case, server would answer like: agh, already logged in
P.S: i'm using http
In NestJS i created backend for my app and i used ReactJS for frontend. When i was testing on localhost everything was working fine.
Then i wanted to try and learn some AWS and i made docker image of my backend and deployed it to EC2. After that i got this url:
http://ec2-<SomeNumbers>.<SomeRegion>.compute.amazonaws.com:8080. If i use this url in Postman and do a POST to my login it works fine. I get back JWT as HttpOnly cookie. In my ReactJS app i replaced localhost links with this new link.
I uploaded my ReactJS app to AWS S3 and got this url http://<bucketName>.s3-website.<Region>.amazonaws.com. If i open this it shows correct first page. The problem comes when i fill login form and click login button the JWT cookie is not set so i get Unauthorized.
I really do not know is the problem in my backend, frontend or in AWS settings.
NestJS controller login function:
async login(
#Body() body: LoginUserDto,
#Res({ passthrough: true }) response: Response,
) {
const data = await this.authService.login(body);
response.cookie('jwt', data, { httpOnly: true });
return 'success';
}
ReactJS code:
const api = axios.create({
baseURL: "http://ec2-<SomeNumbers>.<SomeRegion>.compute.amazonaws.com:8080",
headers: {
"Content-Type": "application/json",
},
withCredentials: true,
});
Thanks!
I'm trying to send cookie from the server to the react app and use this cookie as auth in the middleware. With the postman, everything is working, but in the browser, it is not.
As I have read some tutorials I need to set up cors and here is the snippet of my server-side app.
app.use(cors({ origin: "http://localhost:3000/", credentials: true }));
res.status(200).cookie("login_auth", token, { httpOnly: true, domain: "http://localhost:3000" }).json({ user });
Then I'm sending the post request
axios.post("http://localhost:5000/user/login", { email, password }, { withCredentials: true })
but when I check the cookie storage for my app there is no cookie and further, I have no idea how to send the cookie back to the server to fulfill the middleware. In postman it is all done so easily.
I can save the cookie with the "js-cookie", but I don't think it is the right way to do it.
Cookies.set("login_auth", response.data.token);
Somebody help?
Problem
I'm trying to use server side session (saved on PSQL db) but they are not persisting in between the requests.
Description
I'm running my application locally and is of two parts.
Backend running on MY_IP:2501
Frontend running on MY_IP:3000
Now as per my understanding, Flask saves the session in the "session" table of PSQL (since we are storing server side sessions) and the ID from that particular row is sent to the client in the form of a response header i.e. "Set-Cookie".
Every thing described above is working, but when the React frontend (or browser) receives this header it doesn't creates a cookie out of it because of which the session id is not stored in the frontend and then the frontend is unable to send the same to the backend due to which it is not able to fetch the associated session data resulting in empty session every time.
:(
Stuff I've tried so far..
Done allowing all type of headers while returning the response.
`response.headers.add('Access-Control-Allow-Headers', "Origin, X-Requested-With, Content-Type, Accept, x-auth")`
Done allowing the withCredentials header attribute from front end as well as backend.
Removed HttpOnly parameters from the session using "SESSION_COOKIE_HTTPONLY" config property
Done setting the "SESSION_COOKIE_DOMAIN" same as the front end
NOTE
If I call my API via POSTMAN the session is persisting as the cookie is saved in POSTMAN.
If I run the application on chrome --disable-web-security, then also it works.
Only configuration that is required:
Send the request (REST / GraphQL) with the header withCredentials = true.
Add Access-Control-Allow-Credentials = true headers from the backend.
On Axios (Frontend REST API).
import axios from 'axios';
export const restApi = axios.create({
baseURL: urlBuilder.REST,
withCredentials: true
});
restApi.interceptors.request.use(
function(config) {
config.headers.withCredentials = true; # Sending request with credentials
return config;
},
function(err) {
return Promise.reject(err);
}
);
On Apollo (Frontend GraphQL)
import {
ApolloClient,
ApolloLink
} from 'apollo-boost';
const authLink = new ApolloLink((operation, forward) => {
operation.setContext({
fetchOptions: {
credentials: 'include' . # Sending request with credentials
}
});
return forward(operation);
});
On Python-Flask (Backend)
#app.after_request
def middleware_for_response(response):
# Allowing the credentials in the response.
response.headers.add('Access-Control-Allow-Credentials', 'true')
return response