I have a nest backend that manages people with auth/authorisation for this I'm using session. Everything is working fine using postman.I'll post what matters the Interceptor and the Guard: Guard.ts
canActivate(context: ExecutionContext) {
const request = context.switchToHttp().getRequest();
console.log('REQUEST', request.session);
return request.session.userId;
}
}
My Interceptor:
export function Serialize<T>(dto: ClassType<T>) {
return UseInterceptors(new SerializeInterceptor(dto));
}
export class SerializeInterceptor implements NestInterceptor {
constructor(private dto: any) {}
intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<any> | Promise<Observable<any>> {
return next.handle().pipe(
map((data: any) => {
// PERHAPS classToClass(data, {})
return plainToClass(this.dto, data, {
excludeExtraneousValues: true,
});
}),
);
}
}
My login controller is simple, I post email and password and get an object with this: "id": "364cc066-d631-42ac-b035-00ce83418176", "email": "test@test.com"
Controller
@Post('/signin')
async signIn(
@Body() body: CreateUserDto,
@Session() session: any,
): Promise<UserEntity> {
const user = await this.authService.signIn(body.email, body.password);
session.userId = user.id;
return user;
}
Ok here comes the complicated part. I've created a login page and It's login the user in, but I can't get the session data. It returns my user correctly and I get authorised to enter in the unauthorised routes. But when I try to make a request that has Guards (in my backend) I get 403.
My frontend stuff Here is my Request
export const login = (credentials) => async (dispatch) => {
dispatch(loginStart());
try {
const response = await AlleSysApi.post("/auth/signin", {
email: credentials.email,
password: credentials.password
});
console.log("RESPONSE", response);
Cookies.set("userId", response.data.id);
dispatch(loginSuccess(response.data));
} catch (error) {
dispatch(loginFailure(error.message));
}
};
and my Axios:
export const baseURL = "http://localhost:5000";
const instance = axios.create({
baseURL: baseURL,
});
export default instance;
The protected request that I'm trying to access is this:
export const fetchPersons = () => async (dispatch) => {
dispatch(fetchPersonsStart());
try {
const response = await AlleSysApi.get("/persons");
dispatch(fetchPersonsSuccess(response.data));
} catch (error) {
dispatch(fetchPersonsFailure(error.message));
}
};
The curl is curl -X GET http://localhost:5000/persons -H "Cookie: session=eyJ1c2VySWQiOiIzNjRjYzA2Ni1kNjMxLTQyYWMtYjAzNS0wMGNlODM0MTgxNzYifQ==; session.sig=VLK8b56im3T6gYfY3a060DG7A9E"
I'm using Redux/RTK, But I don't think that this is the problem. I think that I'm missing something during the login to set a session in my frontend.
I've discovered. I wasn't passing the property withCredentials in axios in my request, so I did something like:
export const fetchPersons = () => async (dispatch) => {
dispatch(fetchPersonsStart());
try {
const response = await AlleSysApi.get("/persons", { withCredentials: true });
dispatch(fetchPersonsSuccess(response.data));
} catch (error) {
dispatch(fetchPersonsFailure(error.message));
}
};
It'll be useful to inform that you can't pass withCredentials directly into the main axios instance. Because when you're dealing with non auth routes the cors will block you. Also I've changed main.ts in my backend to handle the cors correctly:
app.enableCors({
allowedHeaders:
'Origin, X-Requested-With, Content-Type, Accept, Authorization',
origin: ['http://localhost:3000'],
credentials: true,
});