I m working a Mobile app using React Native at the front end, NodeJs at the back end. I put an authentication mechanism for this app. Back-end works fine. I've tested with the postman. After login request with correct data, the server sends me a cookie in " Set-cookie" header . Then I put my next request header as "cookie" and I got my data. However, it works differently when I m working with React Native part. I m using Chrome browser to test app for now, and I can see that browser gets a set-cookie header with the response from Login request, (plus I've seen server created a new cookie with user info in it). But for the next request (say its "/home"), it doesn't send the cookie back, so the server doesn't recognize the user and creates a new cookie (with no user info in it) and returns 403 response.
There are some solutions that people suggest that you should do. I m sharing those here but none of them worked for me.
Here is my React Native - Axios code
const axiosObj = axios.create({
baseURL:"http://localhost:3000/",
headers: {
'Content-Type': 'application/json',
},
responseType: 'json',
withCredentials: true,
});
export function get(url){
return new Promise(function(resolve,reject){
axiosObj.get(url).then(res => {
console.log(res)
return res.data
})
})
};
export function post(url,data){
return new Promise(function(resolve,reject){
axiosObj.post(url,data).then(res => {
console.log(res.headers)
const cookies = new Cookies(res.headers.cookie);
console.log("document cookie",document.cookie)
console.log(cookies.getAll());
resolve(res)
})
})
}
At the back end here are the related codes
var app = express();
app.use(cookieParser('keyboard cat'));
var corsOptions = {
origin: '*',
credentials: true,
exposedHeaders: ["Set-Cookie"]
};
app.use(cors(corsOptions))
app.use(logger('dev'));
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));
//session settings
app.use(session({
genid: (req) => {
console.log('Inside the session middleware')
console.log(req.sessionID)
return uuidv4(); // use UUIDs for session IDs
},
store: new FileStore(),
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { httpOnly: false,
expires: new Date(Date.now() + (30 * 86400 * 1000))}
}))
This is my session file at the server after Login
{"cookie":{"originalMaxAge":2591995208,"expires":"2020-09-22T20:22:56.993Z","httpOnly":false,"path":"/"},"passport":{"user":{"_id":"5f307fc99f5c667918a56122","username":"test","__v":0}},"__lastAccess":1598214181785}
What can be the problem here? Any ideas?
edit : I've learned that not reaching "Set-cookie" is normal from front-end (JS). (although in some websites, its said that you can put httpOnly: false in cookie settings and it solves this problem). So it actually doesn't matter if I don't reach the header inside the front end code. I got "set-cookie" header in my response header and chrome doesn't recognize the cookie and put it in cookies section in f12 (also doesn't set it in req.header). That's the problem here
Edit 2: I have some ideas about my problem.
Since I m working with React Native and its not supposed to work in the Chrome browser, it might somehow cause that the browser is not setting cookies. I will create a react project and try to reach the cookie from there. => I solved the problem it was not related to that issue. Although I solved problem when I was testing with react an app
I got a "service-worker.js" error with my react-native code. It doesn't look like it affects the functionality of the code but it might be somehow affected this cookie situation => After solving the problem I still got this error, so it was not related to this.
I also tried a react native app for cookies (react-native-cookie) but it has codes only working with android or ios so it didn't work for the browser.
I solved my problems. It looks like i have 2 problems with my code. First one is in server with cors settings. The first version was like this :
var cors = require('cors');
var corsOptions = {
origin: '*',
credentials: true,
exposedHeaders: ["set-cookie"]
};
app.use(cors(corsOptions))
So basically I was using the cors module for settings. When I create a React app for the test I got a cors error(origin error). Somehow my cors settings didn't work with the library. So I changed this code with the below.
app.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', '*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'Origin,X-Requested-With,content-type,set-cookie');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
// Pass to next layer of middleware
next();
});
and I still had some cors error. One other reason you might get a cors error is that chromes same-origin policy. I m using windows 10 so I opened search bar below and paste there
chrome.exe --user-data-dir="C://Chrome dev session" --disable-web-security
A new chrome browser opened with no web security policy. Then my react app worked fine.I could reach the cookie using document.cookie , also in f12 under application tab >> cookies, I could be able to see my cookie. So google chrome saved my cookie. In the same chrome window, I run my react native app and it also worked successfully. So I thought it was only because security policy of chrome and change my cors settings back and I started to get an error again.
So in conclusion, I had to change 2 things.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.