I have a REST API in ruby on rails and i'm using it with a React frontend and need to get the Authorization header from request response when a user sign in. However i can't acess it, i've exposed the headers already in the rack-cors config file but it still not coming.
Rack-Cors config:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*',
headers: :any,
expose: %w[access-token expiry token-type uid client Authorization],
methods: %i[get post put delete options]
end
end
Request function:
import axios from "axios";
export const api = axios.create({
baseURL: "http://localhost:3000/api/v1",
withCredentials: false,
headers: {
"Content-type": "application/json",
'X-Requested-With': 'XMLHttpRequest',
"Accept": "*/*",
}
});
export const createSession = async (email, password) => {
return api.post('/auth/sign_in', {email, password})
};
Calling the request:
const login = async (email, password, logar) => {
const response = await createSession(email, password);
console.log(response);
const loggedUser = {
"id": response.data.data.id,
"nome": response.data.data.nome,
"email": response.data.email
};
localStorage.setItem("user", JSON.stringify(loggedUser));
setUser(loggedUser);
logar();
navigate('/principal');
};
The response:
I hope somebody could help me, thanks!
Related
I am trying to set up authentication with Remix as my pure frontend and a django backend.
When the user signs in successfully, the backend sends a cookie with the response and this is set in the browser redirect with remix
const signIn = async (credentials: LoginCreds) => {
try {
const response = await fetch(generateFullBackendUrl('/auth/signin'), {
method: 'POST',
body: JSON.stringify(credentials),
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
credentials: 'include'
});
return response;
} catch (e) {
console.log(e);
}
}
const response = await authService.signIn({
email,
password
})
const cookies = response?.headers.get('set-cookie');
if(cookies){
return redirect('profile', {
headers: {
'Set-Cookie': cookies
}
});
However when I try to make subsequent fetch calls in my loader the cookies are not sent to the backend as I would expect the browser would
await fetch(generateFullBackendUrl('api/users/me'), {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
credentials: 'include'
})
Front end is running on port 3000
Backend running on port 4000
Im wondering why the fetch request in the loader does not send the cookies with the request
You need to read the cookie header from the loader request and pass it to your fetch headers.
There’s no way Fetch can automatically know what headers to send when used server side.
There is a quick workaround but not so elegant solution:
in your loader use this:
export const loader: LoaderFunction = async({request}) => {
const response = await fetch(`/api/books?${new URLSearchParams({
limit: '10',
page: '1',
})}`, {
headers: {
'Cookie': request.headers.get('Cookie') || ''
}
});
console.log(response)
if(response.ok) return await response.json();
}
I´m trying to make a POST request to my API, but the CORS policy is blocking the request in the preflight.
I already configured my back-end to accept requests from the front-end origin and to allow all the methods (including OPTIONS and POST).
Here´s my Spring CORS Configuration:
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("https://brazilnews.herokuapp.com", "http://localhost:3000")
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "TRACE", "CONNECT")
.allowedHeaders("append,delete,entries,foreach,get,has,keys,set,values,Authorization")
.allowCredentials(true);
}
Axios Request:
export const api =
axios.create({
baseURL: "http://localhost:8080",
headers: {
"Content-Type": "application/json"
}
});
export const auth = async (email, senha) => {
const body = {
email: email,
senha: senha
}
const res = await api.post("/auth", body)
.then(res => {
console.log(res.data);
}).catch(err => {
console.error(err);
});
return res;
}
Request/Response details:
Console
Solved it by adding this line in the SecurityConfigurations
antMatchers(HttpMethod.OPTIONS, "/**").permitAll()
I am trying to write function to Sign in user with Email and Password.
Using Axios and firebase rest API.
So this is how Axios instance looks like, really simple right? ...
const authUrl = `https://identitytoolkit.googleapis.com/v1/accounts:signInWithPassword?key=${DATABASE_SECRET}`;
const baseURL = "https://beauty-wonderland-e913c-default-rtdb.firebaseio.com";
export const getAxios = (token = null) => {
const config = {
baseURL: baseURL,
headers: {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "DELETE, POST, GET, OPTIONS",
"Access-Control-Allow-Headers":
"Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With",
},
timeout: 10000,
};
if (token !== null) {
// config.headers.Authorization = `Bearer ${token}`;
config.baseURL = authUrl;
config.withCredentials = true;
}
let instance = axios.create(config);
instance.interceptors.request.use(
(request) => {
return request;
},
(error) => {
console.log("axios error: ", error);
return Promise.reject(error);
}
);
instance.interceptors.response.use((response) => {
return response;
});
return instance;
};
This code works fine, flexible and can send any kind of request, but when it comes to authentication, there is problem with sending user data: email and password.
const loginHandler = async () => {
const response = await getAxios("/").post("", {
body: JSON.stringify({
email: "example#example.com",
password: "password",
returnSecureToken: true,
}),
});
const outPut = processResponse(response);
console.log(outPut);
}
so as i guess There is problem with this part
{
body: JSON.stringify({
email: "a#a.com",
password: "123456",
returnSecureToken: true,
}),
});
}
if fetch function works this way
fetch(
`https://identitytoolkit.googleapis.com/v1/accounts:signInWithPasswordkey=${DATABASE_SECRET}`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
email: "example#example.com",
password: "password",
returnSecureToken: true,
}),
}
);
why do axios gives following error:
XMLHttpRequest at ... from origin 'http://localhost:19006' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Please note other get and post request with axios works, and alo authentication works with fetch, only axios shows such an error, please post additional resourses to learn more about firebase rest API and Axios usecases.
This is how error looks like
The baseURL in the axios instance returned by "getAxios" function is https://beauty-wonderland-e913c-default-rtdb.firebaseio.com and not the Auth REST API url. It should be authUrl instead. While in fetch you have hard-coded the URL so the URL is correct for sure.
Edit:
Remove those extraneous headers. You just need content-type as per the docs. I got the same CORS error when I had those.
const config = {
baseURL: baseURL,
headers: {
"Content-Type": "application/json",
},
timeout: 10000,
};
I am trying to make a login page with react using a swagger api: this is the code that i have but it give me this error: POST https://dev.tuten.cl/TutenREST/rest/user/testapis%40tuten.cl 400 (Bad Request)
when i make the test in the API, it gives me an ok, but with my function the result it's 400 BAD REQUEST i can't understand why it's not working:
Can anyone help me?
const onSignIn = async ({ email, password, app }) => {
const result = await fetch('https://dev.tuten.cl/TutenREST/rest/user/testapis%40tuten.cl', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
app,
}),
});
if (result.ok) {
const promiseData = await result.json();
console.log(promiseData);
} else {
console.log('Access is not allowed');
}
};
I have a React app, and an API. When i POST data to APIs login url API responses me back with cookie on successful login, which I have to set, so in each next request user will send this cookie. But I can't find a method to get it from response.
I want to set sessionid, but I can't reach it within code. I tried to do
Cookies.set('sessionid', response.headers['sessionid']);
But it sets undefined. console.log(response.headers) also gives me {content-length: "31", content-type: "application/json"}. Do I do something wrong?
Sender function:
formSender() {
const url_to_send = `${this.state.api_base_url}:${this.state.api_base_port}${this.state.api_user_url}/login/`;
axios.post(url_to_send, `username=${this.state.username}&password=${this.state.password}`, {headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.then((response) => {
// I need to set the cookie here
this.setState({
login_success: response.status === 200,
request_sent: false
});
})
};
Try to set Access-Control-Expose-Headers in the back end or
await axios({
method: 'post',
url: YOUR_URL,
data: Data,
headers: { 'Authorization': 'TOKEN' }
});
I have the same problems and i do that for resolve in backend:
app.use(cors({
origin: true,
credentials: true
}));
and the axios request :
axios({
method: "post",
url: `http://localhost:5500/api/user/login`,
withCredentials: true,
data: {
email,
password,
},
headers: {
"Content-Type": "application/json",
}
})
.then((res) => {
console.log(res);
})
I was initially looking for a solution to setting a cookie from a response, but I realized if it's passed as a Set-Cookie header then it is set by the browser. No need to set it manually. Here is the console view
My app looks something like this:
const app = express();
app.use(cors({
origin: ['http://localhost:3000'],
methods: ['POST', 'PUT', 'GET', 'OPTIONS', 'HEAD'],
credentials: true,
}))
app.use(cookieParser())
app.get('/foo', verifyToken, (req, res) => {
// you can omit verifyToken if you want, it's for bearer auth.
if (true) {
res.cookie('XSRF-TOKEN', 'example')
res.send('Welcome')
} else {
res.sendStatus(403);
}
});
The React side:
<Button onClick={() => {
axios.get('http://localhost:8081/foo', {
params: {},
headers: {
Authorization: `Bearer 123`,
// again, omit ^ if you're not doing bearer auth
},
withCredentials: true,
}
).then((response) => {
console.log('cookie should be set')
})
}}>Express cookie</Button>
Bear in mind if you're deploying to a server both react and express should be on an https connection. Connecting http <-> https causes other issues with cookies.