How to implement a profile? - node.js

I have a token based authorization. Authorization happens well there are no errors. But now need to somehow display the data of an authorized user. Please tell me how to properly implement the profile on the client (Angular 6)?
I have this server:
controller:
const db = require('../config/db.config.js')
const User = db.user
const errorHandler = require('../utils/errorHandler')
module.exports.getProfile = async function(req, res) {
try {
await User.findOne({ id: req.user.id}, (user) => {
res.json({
success: true,
user: user,
message: "Successful"
})
})
}catch(e) {
errorHandler(req, e)
}
}
routes:
const express = require('express')
const router = express.Router()
const controller = require('../controllers/user')
const passport = require('passport')
router.get('/profile', passport.authenticate('jwt', {session: false}), controller.getProfile)
module.exports = router
passport:
const JwtStrategy = require('passport-jwt').Strategy
const ExtractJwt = require('passport-jwt').ExtractJwt
const db = require('../config/db.config.js')
const User = db.user
const options = {
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: process.env.SECRET_OR_KEY
}
module.exports = passport => {
passport.use(
new JwtStrategy(options, async (payload, done) => {
try {
const user = await User.findById(payload.userId).toJSON('username id')
if (user) {
done(null, user)
} else {
done(null, false)
}
} catch(e) {
console.log(e)
}
})
)
}
And here is a part of the client:
app-components:
import { Component, OnInit } from '#angular/core';
import { AuthService } from './shared/services/auth.service';
#Component({
selector: 'app-root',
template: '<router-outlet></router-outlet>'
})
export class AppComponent implements OnInit {
constructor(private auth: AuthService) {
}
ngOnInit() {
const potentialToken = localStorage.getItem('auth-token')
if (potentialToken !== null) {
this.auth.setToken(potentialToken)
}
}
}
auth.service:
import { Injectable, Optional } from "#angular/core";
import { HttpClient } from "#angular/common/http";
import { Router, ActivatedRoute } from "#angular/router";
import { Observable } from "rxjs";
import { tap } from "rxjs/operators";
import { User } from "../interfaces";
#Injectable({
providedIn: 'root'
})
export class AuthService {
private token = null;
constructor(
private http: HttpClient,
#Optional() private _activatedRoute: ActivatedRoute,
#Optional() private _router: Router
) {}
login(user: User): Observable<{token: string}> {
return this.http.post<{token: string}>('/api/auth/login', user)
.pipe(
tap(
({token}) => {
localStorage.setItem('auth-token', token)
this.setToken(token)
}
)
)
}
setToken(token: string) {
this.token = token
}
getToken(): string {
return this.token
}
isAuthenticated(): boolean {
return !!this.token
}
logout() {
this.setToken(null)
localStorage.clear()
}
}
token.interceptor.ts:
import { Injectable } from "#angular/core";
import { AuthService } from "../services/auth.service";
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent, HttpErrorResponse } from "#angular/common/http";
import { Observable, throwError } from "rxjs";
import { catchError } from "rxjs/operators";
import { Router } from "#angular/router";
#Injectable()
export class TokenInterceptor implements HttpInterceptor {
constructor(private auth: AuthService, private router: Router){
}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
if (this.auth.isAuthenticated()) {
req = req.clone({
setHeaders: {
Authorization: this.auth.getToken()
}
})
}
return next.handle(req).pipe(
catchError(
(error: HttpErrorResponse) => this.handleAuthError(error)
)
)
}
private handleAuthError(error: HttpErrorResponse): Observable<any> {
if (error.status === 401) {
this.router.navigate(['/sign_in']), {
queryParams: {
sessionFailed: true
}
}
}
return throwError(error)
}
}
What need to implement on the client to display user data. Tell me please, I'm new.

You just need to create a Service class called UserService which will keep the information related to logged in user.
Whenever login action is performed successfully, just get the user details and fill it in UserService class.
user.service.ts
export class UserService {
private currentUser$: new BehaviorSubject<User>; //<-- check your user type
constructor(private http: Http) { }
getCurrentUser() {
this.currentUser$;
}
setCurrentUser(user:User){
this.currentUser$.next(user); //update the current user
}
}
This service class will give the Observable and you can use it any component or service class.

Related

Inject Service to Guard - Nestjs

I have the following global guard:
authorization.guard.ts
import { ExecutionContext, Injectable } from "#nestjs/common"
import { Reflector } from "#nestjs/core"
import { AuthGuard } from "#nestjs/passport"
#Injectable()
export class AuthorizationGuard extends AuthGuard(["azure-ad"]) {
public constructor(private readonly reflector: Reflector) {
super()
}
async canActivate(context: ExecutionContext) {
const isPublic = this.reflector.get<boolean>(
"isPublic",
context.getHandler(),
)
if (isPublic) {
return true
}
const req = context.switchToHttp().getRequest()
if(req.headers.isbypass){
//help needed
}
const result = (await super.canActivate(context)) as boolean
await super.logIn(req)
return result
}
}
and the following auth module and strategy:
import { Module } from "#nestjs/common";
import { PassportModule } from "#nestjs/passport";
import { UsersModule } from "modules/users/users.module";
import { AzureADStrategy } from "./azureAD.strategy";
import { SessionSerializer } from "./session.serializer";
#Module({
imports: [PassportModule, UsersModule],
providers: [AzureADStrategy, SessionSerializer],
})
export class AuthModule {}
import {
BearerStrategy,
IBearerStrategyOption,
ITokenPayload,
VerifyCallback,
} from "passport-azure-ad";
import {
Inject,
Injectable,
OnModuleInit,
UnauthorizedException,
} from "#nestjs/common";
import passport = require("passport");
import { UsersService } from "modules/users/users.service";
import env from "../../config";
const tenantId = env.TENANT_ID;
const clientID = env.CLIENT_ID || "";
const azureCredentials: IBearerStrategyOption = {
//
};
#Injectable()
export class AzureADStrategy extends BearerStrategy implements OnModuleInit {
onModuleInit() {
passport.use("azure-ad", this);
}
constructor(
#Inject(UsersService) private usersService: UsersService
) {
super(
azureCredentials,
async (token: ITokenPayload, done: VerifyCallback) => {
if (Date.now() / 1000 > token.exp) {
return done(new UnauthorizedException("access token is expired"));
}
const tokenUsername = token?.preferred_username?.slice(0, 9);
const tokenAppId = !tokenUsername && token?.azp;
if (!tokenUsername && !tokenAppId) {
return done(new UnauthorizedException("Missing User"));
}
let user;
if (tokenUsername) {
try {
user = await this.usersService.getUser(
tokenUsername
);
if (!user) {
return done(
new UnauthorizedException("User is not a test user")
);
}
} catch (err) {
return done(err);
}
user.tz = tokenUsername;
} else {
user.appId = tokenAppId;
}
return done(null, user, token);
}
);
}
}
The guard is defined globally using:
const reflector = app.get(Reflector);
app.useGlobalGuards(
new AuthorizationGuard(reflector),
);
And the auth module is imported in app.module.ts:
#Module({
imports: [
AuthModule,
...
]
Now, for the question.
I would like to have a way to "backdoor" the global authorization by checking if req.headers.isbypass exists in the request's headers, and if it does use userService in authorizationGuard, so i can inject the user from the DB to req.user myself and continue the request.
How do I achieve that?
I would change the app.useGlobalGuards() to be a global guard provider, adding
{
provider: APP_GUARD,
useClass: AuthorizationGuard,
}
Into the providers of your AppModule so that Nest handles all of the DI for you. From there, it's just adding the UsersService to the constructor like you already have for the Reflector
#Injectable()
export class AuthorizationGuard extends AuthGuard(["azure-ad"]) {
public constructor(
private readonly reflector: Reflector,
private readonly usersService: UsersServce
) {
super()
}
async canActivate(context: ExecutionContext) {
const isPublic = this.reflector.get<boolean>(
"isPublic",
context.getHandler(),
)
if (isPublic) {
return true
}
const req = context.switchToHttp().getRequest()
if(req.headers.isbypass){
//help needed
}
const result = (await super.canActivate(context)) as boolean
await super.logIn(req)
return result
}
}

Authentication working fine in swagger but responding as unauthorised in frontend app,though it is storing jwt token in the cookie

here is my auth.controller.ts
import { Body, Controller, Get, Post, Req, Res, UnauthorizedException, ValidationPipe } from '#nestjs/common';
import { ApiBadRequestResponse, ApiCreatedResponse, ApiForbiddenResponse, ApiOkResponse, ApiTags, ApiUnauthorizedResponse } from '#nestjs/swagger';
import { User } from 'src/interfaces/user.interface';
import { AuthService } from './auth.service';
import { AuthCredentials } from './dto/auth-credential.dto';
import { Response,Request } from 'express';
import { JwtService } from '#nestjs/jwt';
#ApiTags('auth')
#Controller('auth')
export class AuthController {
constructor(
private authService: AuthService,
private jwtService: JwtService
){}
#Post('/signup')
#ApiCreatedResponse({description: 'this response has created successfully'})
#ApiForbiddenResponse({description: 'Forbidden'})
signUp(#Body(ValidationPipe) authCredentials:AuthCredentials):Promise<User> {
return this.authService.signUp(authCredentials);
}
#Post('/signin')
#ApiOkResponse({description:'The resource has been successfully returned'})
#ApiForbiddenResponse({description:'Invalid credintials'})
async signin(#Body(ValidationPipe) authCredentials:AuthCredentials,#Res() response: Response):Promise<{accessToken:string}> {
const token = await this.authService.signIn(authCredentials);
response
.cookie('access_token', token, {
httpOnly: true,
domain: 'localhost', // your domain here!
expires: new Date(Date.now() + 1000 * 60 * 60 * 24),
// expires: new Date(Date.now() + 60000 ),
})
.send(token);
return token;
}
#Get('/cookies')
findAll(#Req() request: Request) {
console.log(request.cookies['access_token'].accessToken);
// or
// "request.cookies['cookieKey']"
// or
// console.log(request.signedCookies);
}
// to verify the user's token
#Get('/user')
#ApiOkResponse({description:'User varified Successfully'})
#ApiUnauthorizedResponse({description:'Unauthorised User'})
async user(#Req() request: Request) {
try{
const cookies = request.cookies['access_token']
const cookie = cookies.accessToken
const data = await this.jwtService.verifyAsync(cookie)
if(!data) {
throw new UnauthorizedException()
}
const user = await this.authService.findOne(data.username)
return user;
}catch(e){throw new UnauthorizedException()}
}
// to logout by delelting the token
#ApiOkResponse({description:'User varified Successfully'})
#ApiBadRequestResponse({description:'login failed'})
#Post('logout')
async logout(#Res({passthrough: true}) response: Response) {
response.clearCookie('access_token');
return {
message: 'Logged out successfully'
}
}
}
here is my auth.module.ts
import { Module } from '#nestjs/common';
import { APP_GUARD } from '#nestjs/core';
import { JwtModule } from '#nestjs/jwt';
import { PassportModule } from '#nestjs/passport';
import { DatabaseModule } from 'src/database/database.module';
import { AuthController } from './auth.controller';
import { authProviders } from './auth.provider';
import { AuthService } from './auth.service';
import { AuthStrategy } from './auth.strategy';
import { JwtStrategy } from './jwt.strategy';
import { RolesGuard } from './roles.guard';
import { UserRepository } from './user.repository';
#Module({
imports: [
PassportModule.register({defaultStrategy:'jwt'}),
JwtModule.register({
secret: 'abcdefghijklmnop',
signOptions:{
expiresIn: 60000,
}
}),
DatabaseModule],
controllers: [AuthController],
providers: [
...authProviders,
AuthService,
UserRepository,
JwtStrategy,
AuthStrategy,
{
provide: APP_GUARD,
useClass: RolesGuard,
},
// RolesGuard
],
exports: [
JwtStrategy,
PassportModule
]
})
export class AuthModule {}
here is jwt.strategy.ts
import { PassportStrategy } from "#nestjs/passport";
import { Strategy,ExtractJwt } from "passport-jwt"
import { Inject, Injectable, UnauthorizedException } from "#nestjs/common";
import { JwtPayload } from "../interfaces/jwt-payload.interface";
import { Model } from "mongoose";
import { User } from "src/interfaces/user.interface";
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(
#Inject('USER_MODEL')
private authModel: Model<User>,
){
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken('Bearer'),
secretOrKey: 'abcdefghijklmnop',
})
}
async validate(payload: JwtPayload):Promise<User>{
const { username } = payload ;
const user = await this.authModel.findOne({ username }) ;
if(!user){
throw new UnauthorizedException()
}
return user
}
// async validate(payload: any) {
// return { ...payload.user };
// }
}
here is my user.repository.ts
import { BadRequestException, Inject, Injectable, UnauthorizedException } from "#nestjs/common";
import { Model } from "mongoose";
import { User } from "src/interfaces/user.interface";
import { AuthCredentials } from "./dto/auth-credential.dto";
var bcrypt = require('bcryptjs');
#Injectable()
export class UserRepository{
constructor(
#Inject('USER_MODEL')
private authModel: Model<User>
){}
async validateUser(authCredentials):Promise<boolean> {
const username = authCredentials.username
const userExist = await this.authModel.findOne({ username})
if(userExist === null) {return true}
else {return false}
}
async validateUserPassword(authCredentials:AuthCredentials): Promise<string> {
const { username, password } = authCredentials;
const user = await this.authModel.findOne({ username})
if (user === null) {
throw new UnauthorizedException('Invalid credintials')
}else {
const isMatch = await bcrypt.compare(password, user.password)
if (isMatch) {
return user.username
}else {throw new BadRequestException('Invalid credintials')}
}
}
}
this is auth module. I've applicant, application and some other modules too which I've to authenticate. These are working fine in swagger but I've a react frontend app, Which also working partially, means it only storing the token in the cookie but whenever trying to get or access other modules they responses as 401(Unauthorised)

How to fix unknown authentication strategy "jwt" when I inject another service into user service in nestjs

I have a user service that handles registration, login and some other functions. I have been working on the application for sometime now with over 10 modules. But I noticed each time I injected another service and I try to consume any endpoint I get this error "Unknown authentication strategy "jwt". Error on swagger is:-
Internal Server Error
Response body
{
"statusCode": 500,
"message": "Internal server error"
}
Once I remove the injected service from the user module, everything is fine again. I have been trying to fix this because I need to use this service inside the user module.
This is the jwt.Strategy.ts
import { Injectable, HttpException, HttpStatus } from "#nestjs/common";
import { PassportStrategy } from '#nestjs/passport';
import { Strategy, ExtractJwt, VerifiedCallback } from "passport-jwt";
import { AuthService } from './auth.service';
#Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
ignoreExpiration: false,
secretOrKey: process.env.SECRETKEY
});
}
async validate(payload: any, done: VerifiedCallback) {
const user = await this.authService.validateUser(payload);
try {
if (user) {
//return user;
return done(null, user, payload.iat)
} else if (user == null) {
const Terminal = await this.authService.validatePos(payload);
return done(null, Terminal, payload.iat)
}
else {
return done(
//throw new UnauthorizedException();
new HttpException('Unauthorised access', HttpStatus.UNAUTHORIZED),
false,
);
}
} catch (error) {
return error;
}
}
}
This is the AuthModule
import { Module } from '#nestjs/common';
import { AuthService } from './auth.service';
import { UserService } from '../user/user.service';
import { UserSchema } from '../user/user.schema';
import { MongooseModule } from '#nestjs/mongoose';
import { JwtStrategy } from './jwt.strategy';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { ApiKeyStrategy } from './apiKey.strategy';
import { PassportModule } from "#nestjs/passport";
#Module({
imports: [MongooseModule.forFeature([{ name: 'User', schema: UserSchema }]),
PassportModule.register({
secret: "mysec"
}),
ActivityLogService],
providers: [AuthService, UserService, JwtStrategy, ApiKeyStrategy, ActivityLogService],
exports: [AuthService],
controllers: []
})
export class AuthModule { }
This is the api.strategy.ts
import { HeaderAPIKeyStrategy } from 'passport-headerapikey';
import { PassportStrategy } from '#nestjs/passport';
import { Injectable, HttpException, HttpStatus } from '#nestjs/common';
import { AuthService } from './auth.service';
#Injectable()
export class ApiKeyStrategy extends PassportStrategy(HeaderAPIKeyStrategy) {
constructor(private authService: AuthService) {
super({
header: 'api_key',
prefix: ''
}, true,
(apikey: string, done: any, req: any, next: () => void) => {
const checkKey = this.authService.validateApiKey(apikey);
if (!checkKey) {
return done(
new HttpException('Unauthorized access, verify the token is correct', HttpStatus.UNAUTHORIZED),
false,
);
}
return done(null, true, next);
});
}
}
This is the authService
import { Injectable } from '#nestjs/common';
import { sign } from 'jsonwebtoken';
import { UserService } from '../user/user.service';
import { TerminalService } from '../terminal/terminal.service';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { Terminal } from '../terminal/interfaces/terminal.interface';
#Injectable()
export class AuthService {
constructor(private userService: UserService, #InjectModel('Terminal') private terminalModel: Model<Terminal>,) { }
//generate token for user
async signPayLoad(payload: any) {
return sign(payload, process.env.SECRETKEY, { expiresIn: '1h' });
}
//find user with payload
async validateUser(payload: any) {
const returnuser = await this.userService.findByPayLoad(payload);
return returnuser;
}
//generate token for Posy
async signPosPayLoad(payload: any) {
return sign(payload, process.env.SECRETKEY, { expiresIn: '24h' });
}
//find terminal with payload
async validatePos(payload: any) {
const { terminalId } = payload;
const terminal = await this.terminalModel.findById(terminalId);
return terminal;
}
validateApiKey(apiKey: string) {
const keys = process.env.API_KEYS;
const apiKeys = keys.split(',');
return apiKeys.find(key => apiKey === key);
}
}
This is the user service
import { Injectable, HttpException, HttpStatus, Inject } from '#nestjs/common';
import { User } from './interfaces/user.interface';
import { Model } from 'mongoose';
import { InjectModel } from '#nestjs/mongoose';
import { LoginUserDto } from './login-user.dto';
import { ActivityLogService } from '../activity-log/activity-log.service';
import { UpdateUserDTO } from './dtos/update_user.dto';
#Injectable()
export class UserService {
constructor(#InjectModel('User') private userModel: Model<User>,
private activityLogService: ActivityLogService,
) { }
//Login user
private users = [
{
"userId": 1,
"name": "John Doe",
"username": "john",
"password": "john123"
},
]
async login(loginDTO: LoginUserDto) {
const { email, password } = loginDTO;
return await this.users.find(users => users.username == email)
}
async findByPayLoad(payload: any) {
const { userId } = payload;
return await this.userModel.findById(userId)
}
async getAllUser() {
return this.users;
}
}
I cant figure out what I am doing wrong
Besides the code being difficult to manipulate and determine what's happening, services being in places they shouldn't and re-instantiations of services all over the place, the culprit as to why you are getting the error is simply because you never register the PassportModule from #nestjs/passport
EDIT 1/7/2017
Coming back to this answer about a year and a half later, it looks like the real issue is the use of a REQUEST scoped provider in the strategy. The nest docs explicitly mention this can't be done directly but also have a workaround for it.

Interceptor issue in login and logout in angular 8

In my angular application i have used login and logout concept by MEAN(mongo,Express,Angular,Node).
After login within few min if i reload the page automatically going to login page.Token is there but it is redirecting to login page.I do not know why it is happening like this.Below given my code.
auth.guard.ts:
import { Injectable } from '#angular/core';
import { CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from
'#angular/router';
import { Observable } from 'rxjs';
import { UserService } from "../shared/user.service";
import { Router } from "#angular/router";
#Injectable({
providedIn: 'root'
})
export class AuthGuard implements CanActivate {
constructor(private userService : UserService,private router : Router){}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): boolean {
if (!this.userService.isLoggedIn()) {
this.router.navigateByUrl('/login');
this.userService.deleteToken();
return false;
}
return true;
}
}
user.service.ts:
getToken() {
return localStorage.getItem('usertoken');
}
setToken(token: string) {
localStorage.setItem('token', token);
}
getToken() {
return localStorage.getItem('token');
}
deleteToken() {
localStorage.removeItem('token');
}
getUserPayload() {
var token = this.getToken();
if (token) {
var userPayload = atob(token.split('.')[1]);
return JSON.parse(userPayload);
}
else
return null;
}
isLoggedIn() {
var userPayload = this.getUserPayload();
if (userPayload)
return userPayload.exp > Date.now() / 1000;
else
return false;
}
After logged within 2 or 3 min if i refresh the page getting err.error.auth is false.Why it is happening like this?
auth.intercepter.ts:
import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from "#angular/common/http";
import { Injectable } from '#angular/core';
import { tap } from 'rxjs/operators';
import { Router } from "#angular/router";
import { UserService } from "../shared/user.service";
#Injectable()
export class UserAuthInterceptor implements HttpInterceptor {
constructor(private userService : UserService,private router : Router){}
intercept(req: HttpRequest<any>, next: HttpHandler) {
if (req.headers.get('noauth'))
return next.handle(req.clone());
else {
const clonedreq = req.clone({
headers: req.headers.set("Authorization", "Bearer " + this.userService.getToken())
});
return next.handle(clonedreq).pipe(
tap(
event => { },
err => {
if (err.error.auth == false) {
this.router.navigateByUrl('/login'); //After login within 2 or 3 min if i refresh or reload the page this is working.I do not know why this is calling on reload the page
}
})
);
}
}
}

TypeError: token.split is not a function

I Have get some error while login which is not expected but i try to solve it from 2 days but i cannot. I am using Nodejs for the api and angular 7 for the frontend
i have posted some of the code with the error
please help me to solve this
THANK YOU SO MUCH IN ADVANCE
auth.service.ts
import { Injectable } from "#angular/core";
import { Observable } from "rxjs";
import "rxjs/Rx";
import { JwtHelperService } from "#auth0/angular-jwt";
import "core-js/es7/reflect";
import { HttpClient } from "#angular/common/http";
const jwt = new JwtHelperService();
#Injectable()
export class AuthService {
private decodedToken;
constructor(private http: HttpClient) {}
public register(userData: any): Observable<any> {
return this.http.post("/api/v1/users/register", userData);
}
public login(userData: any): Observable<any> {
return this.http.post("/api/v1/users/auth", userData).map(token => {
//debugger;
return this.saveToken(token);
});
}
private saveToken(token): string {
//debugger;
this.decodedToken = jwt.decodeToken(token);
localStorage.setItem("bwm_auth", token.token);
localStorage.setItem("bwm_meta", JSON.stringify(this.decodedToken));
return token;
}
}
login.component.ts
import { Component, OnInit } from "#angular/core";
import { Router, ActivatedRoute } from "#angular/router";
import { AuthService } from "../shared/auth.service";
import { FormBuilder, FormGroup, Validators } from "#angular/forms";
#Component({
selector: "bwm-login",
templateUrl: "./login.component.html",
styleUrls: ["./login.component.scss"]
})
export class LoginComponent implements OnInit {
loginForm: FormGroup;
mistake: any[] = [];
notifyMessage: string = "";
constructor(
private fb: FormBuilder,
private auth: AuthService,
private router: Router,
private route: ActivatedRoute
) {}
ngOnInit() {
this.initForm();
this.route.params.subscribe(params => {
if (params["registered"] == "success") {
//debugger;
this.notifyMessage =
"You have been successfully registered you can login now";
}
});
}
initForm() {
this.loginForm = this.fb.group({
email: [
"",
[
Validators.required,
Validators.pattern(
"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+#[a-zA-Z0-9-]+(?:.[a-zA-Z0-9-]+)*$"
)
]
],
password: ["", Validators.required]
});
}
isInvalidForm(fieldName): boolean {
return (
this.loginForm.controls[fieldName].invalid &&
(this.loginForm.controls[fieldName].dirty ||
this.loginForm.controls[fieldName].touched)
);
}
isRequiredForm(fieldName): boolean {
return this.loginForm.controls[fieldName].errors.required;
}
login() {
// debugger;
//console.log(this.loginForm.value);
this.auth.login(this.loginForm.value).subscribe(
token => {
//debugger;
this.router.navigate(["/rentals"]);
},
errorResponse => {
// debugger;
console.log(errorResponse);
// this.mistake = errorResponse.error.errors;
//this.mistake = errorResponse.error;
}
);
}
}
error in browser
TypeError: token.split is not a function
at JwtHelperService.push../node_modules/#auth0/angular-jwt/src/jwthelper.service.js.JwtHelperService.decodeToken (jwthelper.service.js:70)
at AuthService.push../src/app/auth/shared/auth.service.ts.AuthService.saveToken (auth.service.ts:26)
at MapSubscriber.project (auth.service.ts:20)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:35)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/map.js.MapSubscriber._next (map.js:41)
at MapSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/operators/filter.js.FilterSubscriber._next (filter.js:38)
at FilterSubscriber.push../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.next (Subscriber.js:54)
at MergeMapSubscriber.push../node_modules/rxjs/_esm5/internal/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:84)
error in browser
As it seems the token that is returned from server is not string type
public login(userData: any): Observable<any> {
return this.http.post("/api/v1/users/auth", userData).map(token => {
//debugger;
return this.saveToken(token);
});
}
try to check it what is returned from server

Resources