Cannot get cookie in middleware with node and angular - node.js

I am using nodejs, express, cookie-parser and angular 6. Right now angular runs in http://localhost:4200 and node/express in http://localhost:3000. I also put
const cors = require('cors');
app.use(cors());
in my app.js in node, so both angular and node can communicate.
In my login route I create an http-only cookie with the token and then I send back a JSON with some info and the user id
res.cookie("SESSIONID", token, {httpOnly:true, secure:true});
res.json({ success:true, msg:'you are logged in', userid: resolved.id});
I suppose that the SESSIONID cookie is send with every request back to the server , so I dont have to set it myself before every request
In my middleware, I want to get the token from the cookie in order to check it. So, I do
const token = req.cookies.SESSIONID;
console.log('token from validate : ', token);
//check token and expiration, either next(); or redirect back
in my routes I have
router.get('cms/account', myMiddleware.required(), (req, res)=>{
res.json({ msg:'profile data'});
});
My profile service contacts the account route of node
import { Injectable } from '#angular/core';
import { Http, Headers } from '#angular/http';
import { map } from "rxjs/operators";
#Injectable({
providedIn: 'root'
})
export class ProfileService {
constructor(private http:Http) { }
getProfile(){
return this.http.get('http://localhost:3000/cms/account').pipe(map(res => res.json()));
}
}
my profile service should render some profile data
import { Component, OnInit } from '#angular/core';
import { ProfileService } from '../../services/profile.service';
#Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent implements OnInit {
constructor( private profileService: ProfileService) { }
ngOnInit() {
this.profileService.getProfile().subscribe((data) =>{
console.log('profileService -- ', data);
})
}
}
After I login I go to http://localhost:4200/cms/profile. In the console I see token from validate : undefined
So I am sure that angular successfully reaches until the validation middleware, but cannot get the cookie.
I fail to understand why the cookie is not there. Is it my synatx? Is it not set at the start? Should I include it with every request ? Is it the different ports in localhost ? I gave as much details I could, if you need extra, just tell me. Please help me debug this, because I am lost.
Thanks

Related

Question about token delete form cookies node.js React.js

I'm making Authentication system using jwt with httpOnly cookies in node.js and React.js.
Question is- How should i handle if someone explicitly delete cookie(contain accesstoken) by going to inspect> application >cookies tab in browser?
In my case it should navigate to Login page but it just stay in the home page unless refreshed.
Home.js(send request to verify token on component mount but if cookie deleted stayed on the same page insted going to login page)
import axios from 'axios'
import React, { useEffect } from 'react'
import './Home.css'
import { useNavigate } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux'
import Login from '../../Pages/Login';
function Home() {
const navigate = useNavigate()
useEffect(() => {
axios.get('http://localhost:9000/auth/redirecthome', { withCredentials: true })
.then((res) => {
console.log(res, 'response')
})
.catch((err) => {
console.log(err)
navigate('/login')
})
}, [])
return (
<div className='Home'>Home</div>
)
}
export default Home

http GET request is not sending to the Node Js API in Angular 13

I developed a Node Js API with express and MongoDB. I wanted to fetch data from the database by using Angular front-end. I created a service to call the GET http request from the from-end with a parameter and the getPatient method was called. But the request is not sending to the end point. I opened the inspect and directed to the network and there was no record of a sent request. But when I send the post method to save data to the database , it has worked.. How can I fix this ?
import { Injectable } from '#angular/core';
import {HttpClient} from "#angular/common/http";
import {environment} from "../../environments/environment";
import {Observable} from "rxjs";
#Injectable({
providedIn: 'root'
})
export class PatientService {
baseURL=environment.baseUrl;
constructor(private http:HttpClient) { }
savePatient(name:string , email:string , dob:string , address:string , contact:string , diagnosis:string):Observable<any>{
return this.http.post(this.baseURL + 'patient/save' , {
name:name,
email:email,
dob:dob,
address:address,
contact:contact,
diagnosis:diagnosis
})
}
getPatient(name:string):Observable<any>{
console.log('service called');
return this.http.get<any>(this.baseURL + 'patient/get' , {headers : {name : name}});
}
}

How use Nodejs Localstorage (scratch) with Angular

So I have a stored a token in a file "scratch" inside the assets of angular. I would like to use it in SpotifyService ti finally be authenticated but I dont know how angular can search my file and use it as a token:
Node Js
if (typeof localStorage === "undefined" || localStorage === null) {
var LocalStorage = require('node-localstorage').LocalStorage;
localStorage = new LocalStorage('./src/assets/scratch');
}
...
app.get('/auth/spotify/callback',
passport.authenticate('spotify',{failureRedirect:'/auth/error'}),
function(req,res){
const monToken=localStorage.getItem('token');
res.redirect('/');
})
Angular
import { HttpClient, HttpHeaders } from '#angular/common/http';
import { Injectable } from '#angular/core';
import {} from 'rxjs';
import { JwtHelperService } from "#auth0/angular-jwt";
#Injectable({
providedIn: 'root'
})
export class SpotifyService {
constructor(private http:HttpClient,private jwt:JwtHelperService) {
}
isAuthenticated() : Boolean {
let token=localStorage.getItem('token');
return (token != null && !this.jwt.isTokenExpired(token));
}
setTokenHeader(){
let devant: HttpHeaders=new HttpHeaders();
//devant.append('Content-Type', 'application/json');
let authToken=localStorage.getItem('token');
devant.append('Authorization', `Bearer ${authToken}`);
return devant;
}
private header: HttpHeaders = this.setTokenHeader();
Basically, I don't know how can I use the file 'token' inside. If there's another method to store the token in the API please wirte it bellow
you are doing it all wrong...
why do you wanna store the token in nodejs local storage...?
you don't have to store it just verify the token is valid or not which is passed from the cliend who has saved it

How to check session in angular 8

I have created login form with angular 8 and node js. I have set the session using node js in back end. i couldnt check session set or not in angular for avoid access dashboard without logged in. Kindly suggest the way to use login system using angular 8 and node js. Thanks.....
A very popular method is to use JWT (JSON Web Tokens) npm package to authenticate.
The process would be:
Send credentials to the server
Server generates and sends back JWT or a Bearer Token
FrontEnd would store it in browser cookies or localStorage
localStorage.setItem('TOKEN', tokenReceivedFromServer);
In subsequent Api Calls the token would be sent to the server in a Header (Authorization).
Authorization: `JWT ${localStorage.getItem('TOKEN')}`
FYI: JWT keyword is removed from string on the server before parsing token
The frontend can check if the token is set in storage to show login page / dashboard
First we need to check the login credentials valid or not in application.
In angular application component typescript file, we have send the data service in argument, the service send the values to backend using httpclient. If credentials valid we set the value in localstorage.
submitLogin(data:any)
{
this.LoginService.loginData(data).subscribe(data =>{
if(data.body.status_code == 404)
{
Swal.fire({
icon: 'warning',
title: 'Invalid E-Mail/Password!',
}).then(function(){
});
}else if(data.body.status_code ==200)
{
localStorage.setItem("user_id",data.body.token);
this.router.navigate(['/Dashboard']);
}else
{
Swal.fire({
icon: 'error',
title: 'Process Failed!',
}).then(function(){
});
}
});
}
In service.ts file make sure about those packages import
import { HttpClient } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import {Login} from './login';
in loginData function
url = "http://localhost:3000/loginCheck";
loginData(Login:Login):Observable<any>
{
return this.http.post(this.url,Login,{observe: 'response'});
}
in backend i have used node.js
in file app.js
first install jsonwebtoken package and include in the file.
npm install jsonwebtoken
then set the jsonwebtoken when where condition satisfies
let payload = {subject:employee_id}
let token = jwt.sign(payload,'secretKey')
var response = {
'token': token,
"status_code":200,
}
res.send(response);
res.end();
Whenever we use the login in angular we must use the authguard routing its helps to access dashboard without logged in.
ng generate guard auth
in auth.guard.ts file we must include the package and service
import { CanActivate, Router } from '#angular/router';
import {LoginService} from './login.service';
export class AuthGuard implements CanActivate {
constructor(private LoginService:LoginService,private router:Router) {}
canActivate(): boolean
{
if(this.LoginService.loggedIn())
{
return true
}else
{
this.router.navigate(['/login']);
return false;
}
}
}
In this file we just checking the localstorage value set or not in boolean datatype.
in service file
add the following code for get and return in boolean type
loggedIn()
{
return !!localStorage.getItem('user_id')
}
getToken()
{
return localStorage.getItem('user_id')
}
if its returns true we can access the dasboard, else its redirected to login page.
We must use this canActive function in routing otherwise it will not working
In app-routing.module.ts file
import { AuthGuard } from './auth.guard';
const routes: Routes = [
{path:'Dashboard',component:DashboardComponent},
{path:'receipt',component:ReciptComponentComponent,canActivate:[AuthGuard]},
];
It will helpus to access dashboard without loggedin but we need to check the token valid or not in backend, we can do that using angular interceptors
we should create the new service with interceptors name
ng g service token-interceptor
In interceptor file we need to import the following
import { Injectable,Injector } from '#angular/core';
import { HttpInterceptor } from '#angular/common/http';
import { LoginService } from './login.service';
In interceptors services inject in different way compared to component.
export class TokenInterceptorService implements HttpInterceptor{
constructor(private Injector:Injector) { }
intercept(req:any,next:any)
{
let loginService = this.Injector.get(LoginService);
let tokenzedReq = req.clone({
setHeaders:
{
Authorization: `Bearer ${loginService.getToken()}`
}
});
return next.handle(tokenzedReq)
}
}
we need to create a function in interceptors with the name intercept, then we need to inject the service as per injector.
In backend we need to create the helper function to verify the jsonwebtoken
if the authorization not set we can send the response 401 not found and can redirected to login page
function verifyToken(req,res,next)
{
if(!req.headers.authorization)
{
return res.status(401).send('Unauthorized request');
}
var token = req.headers.authorization.split(' ')[1];
if(!token)
{
return res.status(401).send('Unauthorized request');
}
if(token === 'null')
{
return res.status(401).send('Unauthorized request');
}
//let payload = jwt.verify(token,'secretKey');
let payload = jwt.decode(token,'secretKey');
if(!payload)
{
return res.status(401).send('Unauthorized request');
}
req.userId = payload.subject;
next();
}
then we can use this middleware function wherever we need
for example
app.get('/dashboard',verifyToken,function(req,res){
let events = [];
res.json(events);
});
In dashboard component ts file
this.dashboardService.getData().subscribe(data=>this.dashboardData=data,
err=>{
if(err instanceof HttpErrorResponse)
{
if(err.status===401)
{
this.router.navigate(['/login']);
}
}
})
in dashboard service ts file
url = "http://localhost:3000/dashboard";
getData()
{
return this.http.get<any>(this.url);
}
in app.module.ts file
import { AuthGuard } from './auth.guard';
import { ReciptComponentComponent } from './recipt-component/recipt-component.component';
import { HttpClientModule, HTTP_INTERCEPTORS } from '#angular/common/http';
import { TokenInterceptorService } from './token-interceptor.service';
import { DashboardServiceService } from './dashboard-service.service';
in providers
providers: [AuthGuard,{provide:HTTP_INTERCEPTORS,useClass:TokenInterceptorService,multi:true},DashboardServiceService],

Angular 2+ http.get() stuck in pending status

I have a MEAN app.
Angular CLI: 7.1.4
Node: 10.1.0
OS: win32 x64
Angular: 7.1.4
recently the http requests from HttpClientModule have been getting stuck and not posting to the node server:
Img of chrome dev tools xhr pending request
The nodejs server ( running locally and in production (azure web app) does not indicate that it ever received the request. This happens inconsistently. some times it completes other times it just hangs.
Here is a snippet of a testConnection call from Angular to the server:
Angular service
import { Injectable } from '#angular/core';
import { HttpClient, HttpErrorResponse } from '#angular/common/http';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
import { environment } from '../../environments/environment';
const Headers: any = { withCredentials: true, responseType: 'json', headers: { 'Content-Type': 'application/json' } };
#Injectable({
providedIn: 'root',
})
export class UserService {
constructor(private _http: HttpClient) {}
loginStatus() {
return this._http.get(`${environment.serverURL}/api/login-status`, Headers).pipe(catchError(this.handleError));
}}
Angular Component:
ngOnInit() {
this._userSvc.loginStatus().subscribe(
(result:any)=>{console.log(result)},
(error:any)=>{console.log(error)})
}
Node/express:
router.get('/login-status', (req, res, next) => {
if (req.isAuthenticated()) {
res.status(200).json(req.user);
} else {
res.status(403).json({
success: false,
error: 'User not Authenticated',
message: "Please return to the login in page and try again."
})
}
})
Node is using passport to authenticate
Don't get tied up with the passport issue because its not always this route that fails. I have simple routes that do no validation and just return some text that fail too.
I tried modifying my CORS options but I've only managed to block myself.
There are times when restarting the server will allow the request to finish but not always.
I found the problem and i'm embarrassed to say it was in the SQL connection string for mssql.
I had ((config,error)=>{}) instead of the correct (config,(err)=>{}); This was in the de-serialize user function of passport. Nothing like looking over thousands of lines of code to spot one little problem.

Resources