I saw many similar questions and played with many combinations but nothing works.
I specify that it's all on localhost.
regUser = () => {
var username = getE("username-input").value;
var email = getE("email-input").value;
var password = getE("password-input").value;
axios({
url: process.env.REACT_APP_API_URL + "register",
method: "post",
data: {
username, email, password
},
withCredentials: true
}).then(res => {
if(res.data.regSuccess) {
// Registration successful
this.setState({
regSuccess: true,
regTextHidden: false,
regText: "Registration Successful! An e-mail was sent to the specified e-mail address with confirmation information! You will be redirected to the Login page..."
}, ()=>{
setTimeout(
()=>{window.location.href=("/login")}, 5000
)
})
} else {
this.setState({
regSuccess: false,
regTextHidden: false,
regText: "An error occured. Please try again later!"
})
}
})
}
Backend code:
f.checkPassword(userData, function(result) {
if(!result.correct) {
// Wrong password
res.send({found: true, correct: false})
} else {
// Proceed with authentication
var token = f.genToken(userData.user);
res.header("OPTIONS", 'true')
res.cookie("access-token", token.token, {httpOnly: true, sameSite: "none", maxAge: "100000", secure: false});
res.send({found: true, correct: true})
}
})
No matter what cookie settings I use, they are being sent, the "Set-Cookie" header is present but no cookie is set.
I've played with every option for like 2 days but it just doesn't work. Any advice?
I was stuck on this for a while too. A couple things fixed it for me:
in the frontend in the axios call (which I see you've done), use:
withCredentials: true
Then in the backend in express, use npm package cors, with the following:
const app = express();
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
Or use whatever your url origin is. Hope this works for you.
Related
apologies in advance for what seems like a repeat question.
I've tried lots of other stack overflow and other solutions and cant seem to see what I'm doing wrong.
I'm trying to send and set a cookie from my express server to my front end so that it can be sent back with each request to authenticate.
This is working in insomnia and on the 9090 host but when I push it up to the proper server it just stops working and wont set the cookie at all.
all the headers are showing up
I'm also getting no errors in the console so no help there.
react example of request
export const logIn = (formInput) => {
return listApi.post(`/users/authenticate`, formInput, {withCredentials:true})
.then( ({ data }) => {
return data
})
express
app.use(cors({
origin: "http://192.xxx.x.xx:xxxx",
credentials: true,
origin: true
}));
res.status(200)
.header('Access-Control-Allow-Credentials', true)
.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
.header("Access-Control-Allow-Origin", "http://192.168.1.69:3000")
.header("Access-Control-Allow-Methods", "GET,POST,PATCH,PUT,DELETE,OPTIONS")
.cookie('access_token', token, {expires:tokenExpire,
sameSite: 'None',
secure: true,
httpOnly: true,
Domain: 'http://192.168.1.69:3000'})
.send({ msg: 'success' });
} else {
Promise.reject( {status: 401, msg: 'unauthorized - invalid username and password'})
.catch(err => next(err))
}
};
EDIT:
here are the things I've read so far
res.cookie not setting cookie in browser
Express-Session not working in production/deployment
Express-session cookie not saving in browser
Cookies on localhost with explicit domain
https://www.reddit.com/r/reactjs/comments/vxvdib/cookie_not_being_set_in_react_app_express_backend/
Express doesn't set a cookie
I am creating a React app with a Go server. I set the cookie on the login request's response with http.cookie, which sends it back as seen in the network tab. But the browser doesn't save it. Tried with Chrome and Firefox. What am I doing wrong?
// Cors handler
r.Use(cors.Handler(cors.Options{
AllowOriginFunc: AllowOriginFunc,
AllowedMethods: []string{"GET", "POST", "DELETE"},
AllowedHeaders: []string{"*"},
AllowCredentials: true,
}))
func AllowOriginFunc(r *http.Request, origin string) bool {
if origin == "http://localhost:3000" || origin == "http://127.0.0.1:3000" {
return true
}
return false
}
// End of Login route sending back the token
userDetails := types.User{Name: user.Name, Email: user.Email, Profile_Pic: user.Profile_Pic}
cookie := &http.Cookie{Name: "accessToken", Value: token, MaxAge: int(maxAge), Path: "/api", HttpOnly: true, SameSite: http.SameSiteLaxMode}
http.SetCookie(w, cookie)
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(userDetails)
Edit: Screenshots of the network tab.
Response headers
Request headers
Anybody else who comes across a similar problem, and is using the Fetch API, try setting 'credentials: "include"' in your fetch request that is EXPECTING A COOKIE IN THE RESPONSE. The browser then set the cookie it got in the response.
I had the wrong assumption that the 'credentials' flag must be set for requests that occur after the cookie is received. Finally working. Can't believe I spent 12 hours on setting a cookie smh.
fetch(`${url}/login`, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
credentials: "include", // This here
body: JSON.stringify({
email: userDetails.email,
password: userDetails.password,
}),
}).then((response) => { ...
please try to put you cookie in header filed:"Set-Cookie".
e.g:
w.Header().Set("Set-Cookie","cookieName=cookieValue")
Make sure the response header has this field, and check it in you browser devtools.
I have an express backend API I am hoping to use for authentication, which is using connect-mongodb-session for the express-session store. However, every time I log in, it creates a new session as opposed to using the already existing one. I have done some research and everyone said to simply include credentials in my request, which I already am doing.
Here's some of the backend:
var corsOptions = {
origin: `http://localhost:3000`,
credentials: true
}
app.use(cors(corsOptions))
And here's some of the frontend:
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(formData),
credentials: 'include' as RequestCredentials,
mode: 'cors' as RequestMode,
}
let response = await fetch('http://localhost:8000/register', requestOptions)
As you can see, I have set credentials: 'include' and yet it still creates a new session on every login.
Also, not to ask two questions in one but the frontend is written in React and I'm storing the login info with Redux. This causes my application to log out when reloading, is there any feasible way of dealing with this like logging in with the cookies or persisting the Redux store?
I have changed the cookie option of express-session to secure: false and that seems to have fixed it. Odd, as it was set to true in the first place after someone said that fixed the same issue.
app.use(
session({
secret: process.env.secret,
resave: false,
saveUninitialized: false,
cookie: { secure: false },
store: store,
})
)
add these middleware top of session midleware
because browser send option method before post method use this to ignore option method
app.use(function (req, res, next) {
if (req.method == "OPTIONS") {
res.send();
res.end();
} else {
next();
}
});
I'm building simple react-powered contact page and it would be swell if I could test email sending from my local development machine. I'm using Zoho Email API, which I tested with curl and Insomnia - there everything is fine, I'm able to send emails.
Problems start when I try to do the same from React app via axios. The app itself is served locally via webpack-dev-server. Without proxying request through wds, the browser complains about CORS. But when I'm trying to proxy request via wds with the appropriate headers set I'm being greeted with 400 Bad Request and not much more to aid with the debugging.
The relevant wds setup:
const ReactRefreshWebpackPlugin = require('#pmmmwh/react-refresh-webpack-plugin')
exports.devServer = ({ host, port } = {}) => {
const plugin = new ReactRefreshWebpackPlugin()
return {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers':
'X-Requested-With, content-type, Authorization',
},
proxy: {
'/api/accounts/ZOHO_ID_NOT_SHOWN/messages': {
target: 'https://mail.zoho.eu',
secure: false,
},
},
https: true,
contentBase: path.join(__dirname, 'assets'),
stats: 'errors-only',
historyApiFallback: true,
overlay: true,
hot: true,
host,
port,
},
plugins: [plugin],
}
}
And function in which I'm using to axios to send the email:
const sendEmail = async () => {
const { name, email, message } = formState
try {
const response = await axios({
method: 'post',
url: EMAIL_SEND,
headers: { Authorization: EMAIL_AUTH },
data: {
toAddress: EMAIL_TO,
subject: `Message from ${name} # ${email}`,
content: message,
},
})
console.log(response) // debugging
} catch (e) {
console.log(e.response)
}
}
In the above function, EMAIL_SEND is imported from elsewhere and its value is /api/accounts/ZOHO_ID_NOT_SHOWN/messages - mirroring the wds proxy value.
With the above setup, when I try to send a test email from localhost I'm getting 400 Bad Request... and not much more. I'm sure that the issue is with how I'm proxying the request via wds but I kind of run out of ideas how I can fix it. Any suggestions will be greatly appreciated!
I've used hapi js for my backend and react for my frontend. The front end server is running on localhost port 3000, and the backend on 8000. So i have 2 routes like this -
let userDetails = {
method: "GET",
path: "/api/user/userdata",
config: {
description: 'Get userdata',
notes: 'Returns a todo item by the id passed in the path',
tags: ['api', 'User Data'],
cors: corsHeaders,
auth: {
strategy: 'restricted',
}
},
handler: (request, h) => {
return h.response(userData)
}
}
and
let createUser = {
method: "POST",
path: "/api/user/userdata",
config: {
tags: ['api', 'User Data'],
description: 'Upload User data to the db',
cors: corsHeaders,
},
handler: async (request, h) => {
const { username, emailId, password } = request.payload
request.cookieAuth.set({ username })
return h.response('cookie created!')
}
}
now the 'post' route sets the cookie by request.cookieAuth.set({ username }),
so when i posted through postman application, it's setting the cookie in postman and the get route sends the data without any problem. But in browser, the cookie is'nt being set.
i'm using hapi-auth-cookie plugin and the registration is done like this -
await server.register(HapiAuthCookie)
server.auth.strategy('restricted', 'cookie',{
password: 'AudhASp342SID3acdh83CDASHciAS93rashdiva34a',
cookie: 'session',
isSecure: false,
ttl: 7 * 24 * 60 * 60 * 1000,
})
someone please help